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