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