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