/* @(#)twutil.c 17.1.1.1 (ES0-DMD) 01/25/02 17:48:07 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .IDENTIFICATION twutil.c .AUTHOR Francois Ochsenbein [ESO-IPG] .LANGUAGE C .KEYWORDS Window Management .ENVIRONMENT TermWindows .COMMENTS This module provides various utilities for the window functions, without any physical i/o. Only for internal use. \begin{TeX} \end{TeX} .VERSION 1.0 14-Aug-1986: Creation .VERSION 2.0 03-Dec-1986 New terminal-independant graphic characters with output buffering version. .VERSION 2.1 25-Jun-1987: Version '2' .VERSION 3.0 20-Mar-1988: Version '3' .VERSION 3.1 31-Mar-1989: Added tw_tra (get Achars from Window) .VERSION 3.2 08-Mar-1990: Added third parameter to tw_uw .VERSION 3.3 28-May-1990: Allow hard terminals... ----------------------------------------------------------------------------*/ #define DEBUG 0 /* For debugging only */ #define PM_LEVEL LEVEL_TW /* Only string-like functions */ #define TW_import 0 /* Do not use macro window definitions */ #include #if DEBUG #define DISPLAY(opt) tw_ed(w,opt) #define ENTER_DEBUG(x) ENTER(x) #define EXIT_DEBUG(x) EXIT(x) static WINDOW *wl; #else #define ENTER_DEBUG(x) #define EXIT_DEBUG(x) return(x) #define DISPLAY(opt) #endif MID_EXTERN WINDOW *Screen; MID_EXTERN TERM *terms; MID_STATIC int step = 1; /* Switch used in copy for tw_copy / tw_fill */ MID_STATIC int report = 1; /* Switch used in copy to report modifications*/ static ACHAR fil; MONITOR(TWUTIL); /*========================================================================== * copy *==========================================================================*/ static int copy (wd, xd, as, len) /*+++ .PURPOSE Copy a text (made of short integers), taking care of possible overlay, reporting modified chars. .RETURNS New position in destination window .REMARKS ---*/ WINDOW *wd; /* MOD: The Destination Window */ int xd; /* IN: Absolute destination position */ ACHAR *as; /* IN: The Text to Copy */ int len; /* IN: Length of Text */ { register ACHAR *pd, *ps; ACHAR *pd1; int d, d1, l, J, i, j; LINE *lm; ENTER_DEBUG("+tw_copy/fill"); #if DEBUG TRACE_ED_STR2("Destination Window: ", wd->id, 8); TRACE_ED_I ("Destination Position: ", xd); TRACE_ED_I ("Length: ", len); #endif J = wd->Nj; pd = Aij(wd,xd/J,xd%J); if ((as >= pd) || (step == 0)) /* Use Left to Right */ for (ps = as, d = xd, d1 = d+len; d < d1; d += l) { i = d/J, j = d%J, pd = Aij(wd,i,j); l = MIN(J-j, d1-d); /* Chars that fit on the line */ for (pd1 = pd+l; (pd < pd1) && (*ps == *pd); ps+=step, pd++) ; if (pd == pd1) continue; /* Nothing was modified */ if (report) lm = &M0(wd, i), *lm = MIN(*lm, pd); for (lm = &M1(wd, i); pd < pd1; ps+=step, pd++) { if (*ps != *pd) { *pd = *ps; if (report) *lm = MAX(*lm, pd); } } } else /* Use Right to Left */ for (ps = as+len-1, d1 = xd-1, d = d1+len; d > d1; d -= l) { i = d/J, j = d%J, pd = Aij(wd,i,j); l = MIN(j+1, d-d1); /* Chars that fit on the line */ for (pd1 = pd-l; (pd > pd1) && (*ps == *pd); ps--, pd--) ; if (pd == pd1) continue; /* Nothing was modified */ if (report) lm = &M1(wd, i), *lm = MAX(*lm, pd); for (lm = &M0(wd, i); pd > pd1; ps--, pd--) { if (*ps != *pd) { *pd = *ps; if (report) *lm = MIN(*lm, pd); } } } FIN: EXIT_DEBUG((len > 0 ? xd+len : xd)); } /*========================================================================== * tw_copy *==========================================================================*/ int tw_copy (wd, xd, ps, len) /*+++ .PURPOSE Copy a text (made of short integers), taking care of possible overlay, reporting modified chars. .RETURNS New position in destination window .REMARKS ---*/ WINDOW *wd; /* MOD: The Destination Window */ int xd; /* IN: Absolute destination position */ ACHAR *ps; /* IN: The Text to Copy */ int len; /* IN: Length of Text */ { step = 1; return(copy(wd, xd, ps, len)); } /*========================================================================== * tw_copw *==========================================================================*/ int tw_copw (wd, xd, ws, xs, len) /*+++ .PURPOSE Copy a text (made of short integers), taking care of possible overlay, reporting modified chars. .RETURNS Length .REMARKS ---*/ WINDOW *wd; /* MOD: The Destination Window */ int xd; /* IN: Absolute destination position */ WINDOW *ws; /* IN: The Source Window */ int xs; /* IN: Absolute source position */ int len; /* IN: Length of strings */ { register ACHAR *pd, *ps; int s, s1, l, J, i, j, dx; ENTER_DEBUG("tw_copw"); #if DEBUG TRACE_ED_STR2("Destination Window: ", wd->id, 8); TRACE_ED_I ("Destination Position: ", xd); TRACE_ED_STR2(" Source Window: ", ws->id, 8); TRACE_ED_I (" Source Position: ", xs); TRACE_ED_I ("Length: ", len); #endif J = wd->Nj, pd = Aij(wd,xd/J,xd%J); J = ws->Nj, ps = Aij(ws,xs/J,xs%J); step = 1; dx = xd - xs; if (ps >= pd) /* Use Left to Right */ for (s = xs, s1 = s+len; s < s1; s += l) { j = s%J, ps = Aij(ws,s/J,j); l = MIN(J-j, s1-s); /* Chars that fit on the line */ copy(wd, s+dx, ps, l); } else /* Use Right to Left */ for (s1 = xs-1, s = s1+len; s > s1; s -= l) { j = s%J, ps = Aij(ws,s/J,j); l = MIN(j+1, s-s1); /* Chars that fit on the line */ i = l-1, copy(wd, s+dx-i, ps-i, l); } FIN: EXIT_DEBUG((len > 0 ? xd+len : xd)); } #if DEBUG /*========================================================================== * tw_ed *==========================================================================*/ int tw_ed (w, op) /*+++ .PURPOSE Edit a window (for debugging purposes) .RETURNS OK .REMARKS Option 0: only current parameters --- Option 1: Init and current parameters --- Option 2: Log also the text stored in a window --- Option 3: Log also modified text. Not traced. ---*/ WINDOW *w; /* IN: Window to edit */ int op; /* IN: Option: 0 1 2 3 */ { LINE *lw; register int i, j; register ACHAR *b; static char msg[200]; static char w_id[17] = "W 12345678."; oscopy(&w_id[2], w->id, 8); oscopy(msg, w_id, 10); sprintf(msg+10, ": dim=[%d,%d], Home=[%d,%d], pos=%X, hw=%2X, aw=%2X", w->Ni, w->Nj, w->i0, w->j0, w->wpos, w->hw, w->attr_init); if(op>=1) LOG(msg); sprintf(msg+10, ": pos=[%d,%d], flags=%2X, attr=%2X, next=%d, parent=%d\0", w->pos/w->Nj, w->pos%w->Nj, w->flags, w->attr, Next(w), Parent(w)); LOG(msg); if(op <= 1) return(OK); for (i=0, lw=ALine(w); iNi; i++,lw++) { for (j=0, b= *lw; jNj; j++) msg[j] = (*(b++)) & HIGH; msg[j] = EOS; sprintf(msg+j, " <%d, %d>\0", M0(w,i) - *lw, M1(w,i)- *lw); LOG(msg); } return(OK); } #endif /*========================================================================== * tw_fill *==========================================================================*/ int tw_fill (wd, xd, len, a) /*+++ .PURPOSE Fill the destination window with the character a, reporting modifications. .RETURNS New index. .REMARKS ---*/ WINDOW *wd; /* MOD: The Destination Window */ int xd; /* IN: Absolute destination position */ int len; /* IN: Number od chars */ ACHAR a; /* IN: The fill `char' */ { register int n; ENTER_DEBUG("+tw_fill"); #if DEBUG TRACE_ED_I("Len = ", len); TRACE_ED_I("Dest= ", xd); #endif step = 0, fil = a; n = copy(wd, xd, &fil, len); step = 1; EXIT_DEBUG(n); } /*========================================================================== * posup *==========================================================================*/ static int posup(w, wp, pos) /*+++ .PURPOSE Converts position to parent position .RETURNS Parent position .REMARKS ---*/ WINDOW *w; /* IN: The source window */ WINDOW *wp; /* IN: The parent window */ int pos; /* IN: Position on w */ { return ((pos/w->Nj) * wp->Nj + pos % w->Nj + w->homa); } /*========================================================================== * tw_flags *==========================================================================*/ int tw_flags (w) /*+++ .PURPOSE Set the wpos and hw flags, according to Terminal Capabilities. .RETURNS OK .REMARKS *** For Internal Use *** ---*/ WINDOW *w; /* MOD: Window to modify */ { register WINDOW *wp; short int wh[2]; int J; ENTER_DEBUG("tw_flags"); wp = Parent(w); if (wp) /* Subwindow inherits Echo and Present modes */ { w->flags |= wp->flags & (Echo|Present); wh[0] = wp->home[0], wh[1] = wp->home[1]; J = wp->Nj; } else /* Check if Hardware Scrolling Possible (cs capability) */ wh[0] = 0, wh[1] = 0, J = terms->dim[1]; w->wpos = 0; wh[0] += w->home[0], wh[1] += w->home[1]; if ( wh[0] == 0) w->wpos |= Wu; if ((wh[0] + w->dim[0]) == terms->dim[0]) w->wpos |= Wd; if ( wh[1] == 0) w->wpos |= Wl; if ((wh[1] + w->dim[1]) == terms->dim[1]) w->wpos |= Wr; w->homa = w->i0 * J + w->j0; /* Position on parent window */ w->hw &= TERM_hard; if ( (w->flags & Scroll) /* Look only if required */ && (areSet(w->wpos, Wl|Wr)) /* Full-width window */ && (SearchCap("cs"))) /* cs indicate scrolling region */ w->hw |= Scroll; EXIT_DEBUG(OK); } /*========================================================================== * occluded *==========================================================================*/ static int occluded (w, I, J) /*+++ .PURPOSE Reduce the column range if windows are occluding w. .RETURNS Final length (J[1] - J[0]) .METHOD J is reduced if windows on top overlap completely, or right side occludes a part, of left side. ---*/ WINDOW *w; /* IN: The source window */ int I; /* IN: Screen line position */ short int J[2]; /* MOD: Screen column positions */ { register WINDOW *wc; short int j1; ENTER_DEBUG("occluded"); for (wc = Previous(Screen); (wc != w) && (J[1] > J[0]); wc = Previous(wc)) { #if DEBUG TRACE_ED_STR2("Examine Window: ", wc->id, 8); #endif if_not(wc->flags & Present) continue; /* Removed window */ if (I < wc->i0) continue; /* Line outside */ if (I >= wc->Ni + wc->i0) continue; /* Line outside */ j1 = wc->Nj + wc->j0; if (j1 >= J[0]) if (j1 >= J[1]) J[1] = MIN(J[1], wc->j0); else if (wc->j0 <= J[0]) J[0] = j1; } EXIT_DEBUG(J[1] - J[0]); } /*========================================================================== * reset *==========================================================================*/ static int reset (w, I, J) /*+++ .PURPOSE Reset text from windows on top of w, at screen line I, screen columns between J[0] and J[1]. .RETURNS 1 (there was occlusion) / 0 (nothing occluded) .REMARKS ---*/ WINDOW *w; /* IN: The source window */ int I; /* IN: Screen line position */ short int J[2]; /* IN: Screen column positions */ { register WINDOW *wc; int i, j, l, status; ENTER_DEBUG("reset"); status = 0; #if DEBUG TRACE_ED_STR2("Init Window is: ", w->id, 8); #endif for (wc = Next(w); wc != Screen; wc = Next(wc)) { #if DEBUG TRACE_ED_STR2("Next Window is: ", wc->id, 8); #endif if_not(wc->flags & Present) continue; /* Removed window */ if (I < wc->i0) continue; /* Line outside */ i = I - wc->i0; /* Relative line */ if (i >= wc->Ni) continue; /* Line outside */ j = J[0] - wc->j0; /* Relative Col. */ l = J[1] - J[0]; /* Compute width */ if (j < 0) l += j, j = 0; if (l > wc->Nj - j) l = wc->Nj - j; if (l <= 0) continue; status = 1; copy(Screen, I*Screen->Nj + j + wc->j0, Aij(wc, i, j), l); } EXIT_DEBUG(status); } /*========================================================================== * tw_occluded *==========================================================================*/ int tw_occluded(w, opt) /*+++ .PURPOSE Checks if a window / range is occluded .RETURNS 0 (no occlusion) / 1 (there are occlusions) .METHOD Check line per line. ---*/ WINDOW *w; /* IN: Window to check */ int opt; /* IN: Option 1 for whole window, 0 for range */ { register WINDOW *wp, *wc; int n, pos, l; short int I, J[2]; int limits[2]; ENTER_DEBUG("tw_occluded"); if (w == NULL_WINDOW) EXIT_DEBUG(0); /* Screen can't be occluded! */ if (w == Screen) EXIT_DEBUG(0); /* Screen can't be occluded! */ wp = (Parent(w) ? Parent(w) : w); if (wp == Previous(Screen)) EXIT_DEBUG(0); /* No occlusion */ if (opt) limits[0] = 0, limits[1] = w->Ni * w->Nj; else limits[0] = w->marker[0], limits[1] = w->marker[1]; for (n = limits[0]; n < limits[1]; n += l) { l = w->Nj; l = MIN(l, limits[1] - n); pos = (w == wp ? n : posup(w, wp, n)); pos = posup(wp, Screen, pos); /* Absolute position */ I = pos/Screen->Nj, J[0] = pos%Screen->Nj; J[1] = J[0] + l; for (wc = Previous(Screen); wc != wp; wc = Previous(wc)) { if_not(wc->flags & Present) continue; if ((I >= wc->i0) && (I < wc->Ni + wc->i0) && (J[1] > wc->j0) && (J[0] < wc->Nj + wc->j0)) EXIT_DEBUG(1); } } EXIT_DEBUG(0); } /*========================================================================== * tw_tr *==========================================================================*/ int tw_tr (w, str, len) /*+++ .PURPOSE Translates to ASCII the contents of a window. .RETURNS Length of translated text .REMARKS Only range is translated. Attributes are lost (use tw_tra otherwise). The resulting string is NOT terminated with a null. ---*/ WINDOW *w; /* IN: Window to edit */ char *str; /* OUT: Translated text */ int len; /* IN: Size of string */ { register char *p; ACHAR *pa; WINDOW *wp; int s, s1, j, J; ENTER("+tw_tr"); CheckScreen(w); wp = (w ? w : Screen); len = MIN(len, wp->marker[1] - wp->pos); J = wp->Nj; for (s = wp->pos, s1 = s+len, p = str; s < s1; s+=j, p+=j) { j = s%J, pa = Aij(wp, s/J, j); j = MIN(J-j, s1-s); tv_ac(pa, j, p); } EXIT(p-str); } /*========================================================================== * tw_tra *==========================================================================*/ int tw_tra (w, str, len) /*+++ .PURPOSE Get the contents of a window as a string of ACHAR's .RETURNS Length of text .REMARKS Only range is translated. ---*/ WINDOW *w; /* IN: Window to edit */ ACHAR *str; /* OUT: text */ int len; /* IN: Size of string */ { ACHAR *p, *pa; WINDOW *wp; int s, s1, j, J; ENTER("+tw_tra"); CheckScreen(w); wp = (w ? w : Screen); len = MIN(len, wp->marker[1] - wp->pos); J = wp->Nj; for (s = wp->pos, s1 = s+len, p = str; s < s1; ) { j = s%J, pa = Aij(wp, s/J, j); j = MIN(J-j, s1-s); s += j; while (--j >= 0) *(p++) = *(pa++); } EXIT(p-str); } /*========================================================================== * tw_link *==========================================================================*/ int tw_link (w, wprec) /*+++ .PURPOSE Link window w just following wprec; if wprec is NULL, delete link. .RETURNS OK .REMARKS *** For Internal Use *** The windows are linked from Screen: next pointer of Screen is lowest window, previous pointer of Screen is the top window. The next pointer of the top window is the Screen. Subwindows are linked with null pointers indicating start / end of Subwindow list. ---*/ WINDOW *w; /* MOD: Window to link */ WINDOW *wprec; /* MOD: preceding window */ { register WINDOW *wc, *wp; ENTER_DEBUG("tw_link"); DISPLAY(1); #if DEBUG TRACE_ED_STR2("Relink Window: ", w->id, 8); #endif if (w == wprec) FINISH; /* Nothing to do... */ /* Delete first the link */ #if DEBUG TraceOn(LEVEL_TW); TRACE_ED_STR2("=================Relink Window: ", w->id, 8); #endif wp = Parent(w); /* The parent Window */ wc = Next(w); if (wc) Previous(wc) = Previous(w); wc = Previous(w); if (wc) Next(wc) = Next(w); if(wp) /* It's a child window */ { if(Child(wp) == w) Child(wp) = Next(w); wc = NULL_WINDOW; /* Subwindow link to zero */ } else wc = w; /* Window link to itself */ Previous(w) = wc, Next(w) = wc; /* Make now the link following wprec */ if (wprec) { wc = Next(wprec); /* The next window */ Previous(w) = wprec, Next(w) = wc; Next(wprec) = w; if (wc) Previous(wc) = w; } /* Display Links */ FIN: #if DEBUG TRACE("Complete list of Windows"); if (Screen) for (wc = Next(Screen); wc != Screen; wc = Next(wc)) { if (wc == NULL_WINDOW) break; TRACE_ED_STR2("Window ", wc->id, 8); for (wl = Child(wc); wl; wl = Next(wl)) TRACE_ED_STR2(" SubWindow ", wl->id, 8); } #endif EXIT_DEBUG(OK); } /*========================================================================== * tw_upw *==========================================================================*/ int tw_upw (w) /*+++ .PURPOSE Update parent Window. .RETURNS OK .REMARKS ---*/ WINDOW *w; /* MOD: The source window */ { WINDOW *wp; ENTER_DEBUG("tw_upw"); wp = Parent(w); if (wp) { wp->attr = w->attr; if_not(w->clear) wp->flags &= ~Clear; wp->pos = posup(w, wp, w->pos); } EXIT_DEBUG(OK); } /*========================================================================== * tw_uc *==========================================================================*/ int tw_uc (w) /*+++ .PURPOSE Update cursor position and attributes on the screen .RETURNS OK .REMARKS ---*/ WINDOW *w; /* MOD: The source window */ { register WINDOW *wp; ENTER_DEBUG("tw_uc"); DISPLAY(1); /* Report on Parent Window */ wp = Parent(w); if (wp) tw_upw(w); else wp = w; Screen->pos = posup(wp, Screen, wp->pos); /* = wp->pos/wp->Nj) * Screen->Nj + wp->pos % wp->Nj + wp->homa; */ Screen->attr = wp->attr; EXIT_DEBUG(OK); } /*========================================================================== * tw_uflag *==========================================================================*/ int tw_uflag (w, option) /*+++ .PURPOSE Specify if lines are modified .RETURNS OK .REMARKS Option is zero to specify that all lines have no modifications, non-zero that lines are completely modified. ---------*/ WINDOW *w; /* MOD: Concerned window */ int option; /* IN: Fully modified / no modification */ { int i, j1; LINE *l0, *l1; ACHAR *b; if_not(w) w = Screen; for (i = w->Ni, j1 = w->Nj-1; --i >=0; ) { l0 = &M0(w,i), l1 = &M1(w,i), b = Aij(w, i, 0); if_not(Parent(w)) *l0 = b, *l1 = b + j1; /* No Parent Window */ else *l0 = MIN(*l0, b), *l1 = MAX(*l1, b+j1); if_not(option) /* All modification sentinels removed */ *l1 = NULL_ACHAR, *l0 += terms->dim[1]; } return(OK); } /*========================================================================== * tw_ufl1 *==========================================================================*/ int tw_uattr(wd, xd, len, blank) /*+++ .PURPOSE Change attribute for characters xd to (xd+len). .RETURNS New position in destination window .REMARKS ---*/ WINDOW *wd; /* MOD: The Destination Window */ int xd; /* IN: Absolute destination position */ int len; /* IN: Length of Text */ ACHAR blank; /* IN: New attribute */ { ACHAR *pd, *pd1; ACHAR new_attr, nul_attr; int d, d1, l, J, i, j; LINE *lm0, *lm1; ENTER_DEBUG("+tw_uattr"); #if DEBUG TRACE_ED_STR2("Destination Window: ", wd->id, 8); TRACE_ED_I ("Destination Position: ", xd); TRACE_ED_I ("Length: ", len); #endif J = wd->Nj; nul_attr = (_REVERSE_|_UNDERSCORE_|_BLINK_|_BOLD_)<<8; new_attr = blank & nul_attr; for (d = xd, d1 = d+len; d < d1; d += l) { i = d/J, j = d%J, pd = Aij(wd,i,j); l = MIN(J-j, d1-d); /* Chars that fit on the line */ lm0 = &M0(wd, i), lm1 = &M1(wd, i); for (pd1 = pd+l; pd < pd1; pd++) { if ((*pd & nul_attr) == new_attr) continue; *pd = (*pd & (~nul_attr)) | new_attr; *lm0 = MIN(*lm0, pd); *lm1 = MAX(*lm1, pd); } } FIN: EXIT_DEBUG((len > 0 ? xd+len : xd)); } /*========================================================================== * tw_uw *==========================================================================*/ int tw_uw (w, option, prev) /*+++ .PURPOSE Copy to Screen modifications of a window .RETURNS OK .REMARKS Option is used to specify which modifications are to be copied; it consists of 3 bits: \begin{TeX} \begin{itemize} \item the last bit (1) specifies what to output on Screen: \begin{itemize} \item 0 : Report only the modified part of the window \item 1 : Report whole window to Screen. \end{itemize} \item The previous bit (2) specifies: \begin{itemize} \item 0 : report modification flags on the screen \item 1 : do not report modification flags on the screen (\eg after a scroll performed \via a hardware function) \end{itemize} \item The previous bit (4) specifies: \begin{itemize} \item 0 : --- \item 1 : fill the portion of the Screen covered by window with blanks (removed window) \end{itemize} \item The previous bit (8) specifies: \begin{itemize} \item 0 : --- \item 1 : Place the window just after prev (raise / lower /etc) \end{itemize} \item The previous bit (16) specifies that it's a hard terminal, and therefore the screen is blank. \end{itemize} \end{TeX} ---*/ WINDOW *w; /* MOD: The source window */ int option; /* IN: Specification of how to report modifications */ WINDOW *prev; /* IN: place window just after */ { LINE *p0, *p1; int i, j, I; short int J[2]; WINDOW *wp, *wl; ENTER_DEBUG("tw_uw"); #if DEBUG tw_ed(w,2); #endif /* Report modifications on Parent Window, if necessary */ wp = Parent(w); if (wp) tw_upw(w); else wp = w; wl = (option & 8 ? prev : NULL_WINDOW); /* Modify Link if asked (option & 8) */ if (wl) tw_link(wp, wl); /* If the whole window is considered as modified, flag all lines */ if (option & 1) tw_uflag(wp, 1); /* Option 4 : Remove the (parent) window * and clear corresponding part of Screen */ if (option & 4) { if (wp->wpos == Screen->wpos) Screen->flags |= Clear; for (I = wp->homa, i = wp->Ni; --i >= 0; I += Screen->Nj) tw_fill(Screen, I, wp->Nj, Screen->attr_init); tw_uflag(wp, 0); /* Nothing modified */ } if (wp == Screen) /* The window is the Screen: Nothing else to do */ FINISH; /* For hard terminals, the screen is always clear. */ if (option & 16) { for (I = wp->homa, i = wp->Ni; --i >= 0; I += Screen->Nj) tw_fill(Screen, I, wp->Nj, Screen->attr_init); tw_uflag(Screen, 0); /* Nothing modified */ } /* Test if the screen will be clear */ if ((wp->clear) && (Screen->wpos == wp->wpos)) Screen->flags |= Clear; /* Window occupies complete screen */ /* Finally, copy text to Screen, taking occluding possibilities * into account. */ J[0] = wp->j0; /* Absolute column */ J[1] = wp->j0 + wp->Nj; /* End of column */ for (i = wp->Ni; --i >=0; ) { p1 = &M1(wp,i); p0 = &M0(wp, i); /* First modified `char' */ I = i + wp->i0; /* Line pos. on Screen */ if (*p1) /* Modifications on this line. * Never executed for RemoveWin */ { j = *p0 - Aij(wp,i,0); /* Pos of first modified `char' */ J[0] = j + wp->j0 ; /* Col. pos on Screen */ J[1] = J[0]+ 1 + (*p1 - *p0); /* Last column + 1 */ j = J[0]; if (occluded(wp,I,J) > 0) /* Not Completely occluded */ { if_not(wp->clear) Screen->flags &= ~Clear; if (option&2) report=0; /* Don't report modifs */ j = J[0] - j; /* Offset from *p0 */ copy(Screen, I*Screen->Nj+J[0], *p0 + j, J[1]-J[0]); report=1; } } else if_not(wl) continue; /* No modif, no change in * Windows order... */ /* Reset text from upper windows */ if (reset(wp, I, J)) Screen->flags &=~Clear; *p1 = NULL_ACHAR; *p0 += wp->Nj; } #if DEBUG tw_ed(Screen,2); #endif FIN: EXIT_DEBUG(OK); }