xref: /original-bsd/lib/libcurses/refresh.c (revision 6fcea464)
1 /*
2  * Copyright (c) 1981 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)refresh.c	5.3 (Berkeley) 06/30/88";
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 
29 # ifdef DEBUG
30 # define	STATIC
31 # else
32 # define	STATIC	static
33 # endif
34 
35 STATIC short	ly, lx;
36 
37 STATIC bool	curwin;
38 
39 WINDOW	*_win = NULL;
40 
41 wrefresh(win)
42 reg WINDOW	*win;
43 {
44 	reg short	wy;
45 	reg int		retval;
46 	reg WINDOW	*orig;
47 
48 	/*
49 	 * make sure were in visual state
50 	 */
51 	if (_endwin) {
52 		_puts(VS);
53 		_puts(TI);
54 		_endwin = FALSE;
55 	}
56 
57 	/*
58 	 * initialize loop parameters
59 	 */
60 
61 	ly = curscr->_cury;
62 	lx = curscr->_curx;
63 	wy = 0;
64 	_win = win;
65 	curwin = (win == curscr);
66 
67 	if (win->_clear || curscr->_clear || curwin) {
68 		if ((win->_flags & _FULLWIN) || curscr->_clear) {
69 			_puts(CL);
70 			ly = 0;
71 			lx = 0;
72 			if (!curwin) {
73 				curscr->_clear = FALSE;
74 				curscr->_cury = 0;
75 				curscr->_curx = 0;
76 				werase(curscr);
77 			}
78 			touchwin(win);
79 		}
80 		win->_clear = FALSE;
81 	}
82 	if (!CA) {
83 		if (win->_curx != 0)
84 			_putchar('\n');
85 		if (!curwin)
86 			werase(curscr);
87 	}
88 # ifdef DEBUG
89 	fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin);
90 	fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
91 # endif
92 	for (wy = 0; wy < win->_maxy; wy++) {
93 # ifdef DEBUG
94 		fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy],
95 			win->_lastch[wy]);
96 # endif
97 		if (win->_firstch[wy] != _NOCHANGE)
98 			if (makech(win, wy) == ERR)
99 				return ERR;
100 			else {
101 				if (win->_firstch[wy] >= win->_ch_off)
102 					win->_firstch[wy] = win->_maxx +
103 							    win->_ch_off;
104 				if (win->_lastch[wy] < win->_maxx +
105 						       win->_ch_off)
106 					win->_lastch[wy] = win->_ch_off;
107 				if (win->_lastch[wy] < win->_firstch[wy])
108 					win->_firstch[wy] = _NOCHANGE;
109 			}
110 # ifdef DEBUG
111 		fprintf(outf, "\t%d\t%d\n", win->_firstch[wy],
112 			win->_lastch[wy]);
113 # endif
114 	}
115 
116 	if (win == curscr)
117 		domvcur(ly, lx, win->_cury, win->_curx);
118 	else {
119 		if (win->_leave) {
120 			curscr->_cury = ly;
121 			curscr->_curx = lx;
122 			ly -= win->_begy;
123 			lx -= win->_begx;
124 			if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
125 			    lx < win->_maxx) {
126 				win->_cury = ly;
127 				win->_curx = lx;
128 			}
129 			else
130 				win->_cury = win->_curx = 0;
131 		}
132 		else {
133 			domvcur(ly, lx, win->_cury + win->_begy,
134 				win->_curx + win->_begx);
135 			curscr->_cury = win->_cury + win->_begy;
136 			curscr->_curx = win->_curx + win->_begx;
137 		}
138 	}
139 	retval = OK;
140 ret:
141 	_win = NULL;
142 	fflush(stdout);
143 	return retval;
144 }
145 
146 /*
147  * make a change on the screen
148  */
149 STATIC
150 makech(win, wy)
151 reg WINDOW	*win;
152 short		wy;
153 {
154 	reg char	*nsp, *csp, *ce;
155 	reg short	wx, lch, y;
156 	reg int		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 (*nsp != *csp && wx <= lch) {
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, nlsp = %d\n", clsp, nlsp);
208 # endif
209 					if (clsp - nlsp >= strlen(CE)
210 					    && clsp < win->_maxx) {
211 # ifdef DEBUG
212 						fprintf(outf, "MAKECH: using CE\n");
213 # endif
214 						_puts(CE);
215 						lx = wx + win->_begx;
216 						while (wx++ <= clsp)
217 							*csp++ = ' ';
218 						return OK;
219 					}
220 					ce = NULL;
221 				}
222 				/*
223 				 * enter/exit standout mode as appropriate
224 				 */
225 				if (SO && (*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) {
226 					if (*nsp & _STANDOUT) {
227 						_puts(SO);
228 						curscr->_flags |= _STANDOUT;
229 					}
230 					else {
231 						_puts(SE);
232 						curscr->_flags &= ~_STANDOUT;
233 					}
234 				}
235 				wx++;
236 				if (wx >= win->_maxx && wy == win->_maxy - 1)
237 					if (win->_scroll) {
238 					    if ((curscr->_flags&_STANDOUT) &&
239 					        (win->_flags & _ENDLINE))
240 						    if (!MS) {
241 							_puts(SE);
242 							curscr->_flags &= ~_STANDOUT;
243 						    }
244 					    if (!curwin)
245 						_putchar((*csp = *nsp) & 0177);
246 					    else
247 						_putchar(*nsp & 0177);
248 					    if (win->_flags&_FULLWIN && !curwin)
249 						scroll(curscr);
250 					    ly = win->_begy+win->_cury;
251 					    lx = win->_begx+win->_curx;
252 					    return OK;
253 					}
254 					else if (win->_flags&_SCROLLWIN) {
255 					    lx = --wx;
256 					    return ERR;
257 					}
258 				if (!curwin)
259 					_putchar((*csp++ = *nsp) & 0177);
260 				else
261 					_putchar(*nsp & 0177);
262 # ifdef FULLDEBUG
263 				fprintf(outf,
264 					"MAKECH:putchar(%c)\n", *nsp & 0177);
265 # endif
266 				if (UC && (*nsp & _STANDOUT)) {
267 					_putchar('\b');
268 					_puts(UC);
269 				}
270 				nsp++;
271 			}
272 # ifdef DEBUG
273 			fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
274 # endif
275 			if (lx == wx + win->_begx)	/* if no change */
276 				break;
277 			lx = wx + win->_begx;
278 			if (lx >= COLS && AM) {
279 				lx = 0;
280 				ly++;
281 				/*
282 				 * xn glitch: chomps a newline after auto-wrap.
283 				 * we just feed it now and forget about it.
284 				 */
285 				if (XN) {
286 					_putchar('\n');
287 					_putchar('\r');
288 				}
289 			}
290 		}
291 		else if (wx <= lch)
292 			while (*nsp == *csp && wx <= lch) {
293 				nsp++;
294 				if (!curwin)
295 					csp++;
296 				++wx;
297 			}
298 		else
299 			break;
300 # ifdef DEBUG
301 		fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
302 # endif
303 	}
304 	return OK;
305 }
306 
307 /*
308  * perform a mvcur, leaving standout mode if necessary
309  */
310 STATIC
311 domvcur(oy, ox, ny, nx)
312 int	oy, ox, ny, nx; {
313 
314 	if (curscr->_flags & _STANDOUT && !MS) {
315 		_puts(SE);
316 		curscr->_flags &= ~_STANDOUT;
317 	}
318 	mvcur(oy, ox, ny, nx);
319 }
320