1 /*
2 * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
13 */
14
15 /*LINTLIBRARY*/
16
17 #ifndef lint
18 static char
19 sccsid[] = "@(#)refresh.c 1.8 89/08/24 SMI"; /* from UCB 5.1 85/06/07 */
20 #endif /* not lint */
21
22 /*
23 * make the current screen look like "win" over the area coverd by
24 * win.
25 */
26
27 #include "curses.ext"
28 #include <term.h>
29 #include <string.h>
30
31 #ifdef DEBUG
32 #define DEBUGSTATIC
33 #else
34 #define DEBUGSTATIC static
35 #endif
36
37 DEBUGSTATIC short ly, lx;
38 DEBUGSTATIC bool curwin;
39 WINDOW *_win = NULL;
40
41 /* forward declarations */
42 DEBUGSTATIC void domvcur(int, int, int, int);
43 DEBUGSTATIC int makech(WINDOW *, short);
44
45 int
wrefresh(WINDOW * win)46 wrefresh(WINDOW *win)
47 {
48 short wy;
49 int retval;
50
51 /*
52 * make sure were in visual state
53 */
54 if (_endwin) {
55 (void) _puts(VS);
56 (void) _puts(TI);
57 _endwin = FALSE;
58 }
59
60 /*
61 * initialize loop parameters
62 */
63
64 ly = curscr->_cury;
65 lx = curscr->_curx;
66 _win = win;
67 curwin = (win == curscr);
68
69 if (win->_clear || curscr->_clear || curwin) {
70 if ((win->_flags & _FULLWIN) || curscr->_clear) {
71 (void) _puts(CL);
72 ly = 0;
73 lx = 0;
74 if (!curwin) {
75 curscr->_clear = FALSE;
76 curscr->_cury = 0;
77 curscr->_curx = 0;
78 (void) werase(curscr);
79 }
80 (void) touchwin(win);
81 }
82 win->_clear = FALSE;
83 }
84 if (!CA) {
85 if (win->_curx != 0)
86 (void) _putchar('\n');
87 if (!curwin)
88 (void) werase(curscr);
89 }
90 #ifdef DEBUG
91 fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin);
92 fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
93 #endif
94 for (wy = 0; wy < win->_maxy; wy++) {
95 #ifdef DEBUG
96 fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy],
97 win->_lastch[wy]);
98 #endif
99 if (win->_firstch[wy] != _NOCHANGE)
100 if (makech(win, wy) == ERR)
101 return (ERR);
102 else {
103 if (win->_firstch[wy] >= win->_ch_off)
104 win->_firstch[wy] = win->_maxx +
105 win->_ch_off;
106 if (win->_lastch[wy] < win->_maxx +
107 win->_ch_off)
108 win->_lastch[wy] = win->_ch_off;
109 if (win->_lastch[wy] < win->_firstch[wy])
110 win->_firstch[wy] = _NOCHANGE;
111 }
112 #ifdef DEBUG
113 fprintf(outf, "\t%d\t%d\n", win->_firstch[wy],
114 win->_lastch[wy]);
115 #endif
116 }
117
118 if (win == curscr)
119 domvcur(ly, lx, win->_cury, win->_curx);
120 else {
121 if (win->_leave) {
122 curscr->_cury = ly;
123 curscr->_curx = lx;
124 ly -= win->_begy;
125 lx -= win->_begx;
126 if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
127 lx < win->_maxx) {
128 win->_cury = ly;
129 win->_curx = lx;
130 }
131 else
132 win->_cury = win->_curx = 0;
133 } else {
134 domvcur(ly, lx, win->_cury + win->_begy,
135 win->_curx + win->_begx);
136 curscr->_cury = win->_cury + win->_begy;
137 curscr->_curx = win->_curx + win->_begx;
138 }
139 }
140 retval = OK;
141
142 _win = NULL;
143 (void) fflush(stdout);
144 return (retval);
145 }
146
147 /*
148 * make a change on the screen
149 */
150
151 DEBUGSTATIC int
makech(WINDOW * win,short wy)152 makech(WINDOW *win, short wy)
153 {
154 char *nsp, *csp, *ce;
155 short wx, lch, y;
156 intptr_t nlsp, clsp; /* last space in lines */
157
158 wx = win->_firstch[wy] - win->_ch_off;
159 if (wx >= win->_maxx)
160 return (OK);
161 else if (wx < 0)
162 wx = 0;
163 lch = win->_lastch[wy] - win->_ch_off;
164 if (lch < 0)
165 return (OK);
166 else if (lch >= win->_maxx)
167 lch = win->_maxx - 1;
168 y = wy + win->_begy;
169
170 if (curwin)
171 csp = " ";
172 else
173 csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
174
175 nsp = &win->_y[wy][wx];
176 if (CE && !curwin) {
177 for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--)
178 if (ce <= win->_y[wy])
179 break;
180 nlsp = ce - win->_y[wy];
181 }
182
183 if (!curwin)
184 ce = CE;
185 else
186 ce = NULL;
187
188 while (wx <= lch) {
189 if (*nsp != *csp) {
190 domvcur(ly, lx, y, wx + win->_begx);
191 #ifdef DEBUG
192 fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx);
193 #endif
194 ly = y;
195 lx = wx + win->_begx;
196 while (wx <= lch && *nsp != *csp) {
197 if (ce != NULL && wx >= nlsp && *nsp == ' ') {
198 /*
199 * check for clear to end-of-line
200 */
201 ce = &curscr->_y[ly][COLS - 1];
202 while (*ce == ' ')
203 if (ce-- <= csp)
204 break;
205 clsp = ce - curscr->_y[ly] - win->_begx;
206 #ifdef DEBUG
207 fprintf(outf, "MAKECH: clsp = %d,"
208 " nlsp = %d\n", clsp, nlsp);
209 #endif
210 if (clsp - nlsp >= strlen(CE) &&
211 clsp < win->_maxx) {
212 #ifdef DEBUG
213 fprintf(outf, "MAKECH: using"
214 " CE\n");
215 #endif
216 (void) _puts(CE);
217 lx = wx + win->_begx;
218 while (wx++ <= clsp)
219 *csp++ = ' ';
220 return (OK);
221 }
222 ce = NULL;
223 }
224 /*
225 * enter/exit standout mode as appropriate
226 */
227 if (SO && (*nsp&_STANDOUT) !=
228 (curscr->_flags&_STANDOUT)) {
229 if (*nsp & _STANDOUT) {
230 (void) _puts(SO);
231 curscr->_flags |= _STANDOUT;
232 } else {
233 (void) _puts(SE);
234 curscr->_flags &= ~_STANDOUT;
235 }
236 }
237 wx++;
238 if (wx >= win->_maxx && wy == win->_maxy - 1)
239 if (win->_scroll) {
240 if ((curscr->_flags&_STANDOUT) &&
241 (win->_flags & _ENDLINE))
242 if (!MS) {
243 (void) _puts(SE);
244 curscr->_flags &=
245 ~_STANDOUT;
246 }
247 if (!curwin)
248 (void) _putchar((*csp = *nsp) &
249 0177);
250 else
251 (void) _putchar(*nsp & 0177);
252 if (win->_flags&_FULLWIN && !curwin)
253 (void) scroll(curscr);
254 if (!curwin) {
255 ly = wy + win->_begy;
256 lx = wx + win->_begx;
257 } else {
258 ly = win->_begy+win->_cury;
259 lx = win->_begx+win->_curx;
260 }
261 return (OK);
262 } else if (win->_flags&_SCROLLWIN) {
263 wx = wx - 1;
264 lx = wx;
265 return (ERR);
266 }
267 if (!curwin)
268 (void) _putchar((*csp++ = *nsp) & 0177);
269 else
270 (void) _putchar(*nsp & 0177);
271 #ifdef FULLDEBUG
272 fprintf(outf,
273 "MAKECH:putchar(%c)\n", *nsp & 0177);
274 #endif
275 if (UC && (*nsp & _STANDOUT)) {
276 (void) _putchar('\b');
277 (void) _puts(UC);
278 }
279 nsp++;
280 }
281 #ifdef DEBUG
282 fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
283 #endif
284 if (lx == wx + win->_begx) /* if no change */
285 break;
286 lx = wx + win->_begx;
287 if (lx >= COLS && AM) {
288 lx = 0;
289 ly++;
290 /*
291 * xn glitch: chomps a newline after auto-wrap.
292 * we just feed it now and forget about it.
293 */
294 if (XN) {
295 (void) _putchar('\n');
296 (void) _putchar('\r');
297 }
298 }
299 } else if (wx <= lch)
300 while (wx <= lch && *nsp == *csp) {
301 nsp++;
302 if (!curwin)
303 csp++;
304 ++wx;
305 }
306 else
307 break;
308 #ifdef DEBUG
309 fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
310 #endif
311 }
312 return (OK);
313 }
314
315 /*
316 * perform a mvcur, leaving standout mode if necessary
317 */
318
319 DEBUGSTATIC void
domvcur(int oy,int ox,int ny,int nx)320 domvcur(int oy, int ox, int ny, int nx)
321 {
322 if (curscr->_flags & _STANDOUT && !MS) {
323 (void) _puts(SE);
324 curscr->_flags &= ~_STANDOUT;
325 }
326 (void) mvcur(oy, ox, ny, nx);
327 }
328