This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / lib / libcurses / refresh.c
CommitLineData
15637ed4
RG
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, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)refresh.c 5.5 (Berkeley) 3/3/91";
36#endif /* not lint */
37
38/*
39 * make the current screen look like "win" over the area coverd by
40 * win.
41 */
42
43# include "curses.ext"
44
45# ifdef DEBUG
46# define STATIC
47# else
48# define STATIC static
49# endif
50
51STATIC short ly, lx;
52
53STATIC bool curwin;
54
55WINDOW *_win = NULL;
56
57STATIC int domvcur(), makech();
58
59wrefresh(win)
60reg WINDOW *win;
61{
62 reg short wy;
63 reg int retval;
64 reg WINDOW *orig;
65
66 /*
67 * make sure were in visual state
68 */
69 if (_endwin) {
70 _puts(VS);
71 _puts(TI);
72 _endwin = FALSE;
73 }
74
75 /*
76 * initialize loop parameters
77 */
78
79 ly = curscr->_cury;
80 lx = curscr->_curx;
81 wy = 0;
82 _win = win;
83 curwin = (win == curscr);
84
85 if (win->_clear || curscr->_clear || curwin) {
86 if ((win->_flags & _FULLWIN) || curscr->_clear) {
87 _puts(CL);
88 ly = 0;
89 lx = 0;
90 if (!curwin) {
91 curscr->_clear = FALSE;
92 curscr->_cury = 0;
93 curscr->_curx = 0;
94 werase(curscr);
95 }
96 touchwin(win);
97 }
98 win->_clear = FALSE;
99 }
100 if (!CA) {
101 if (win->_curx != 0)
102 _putchar('\n');
103 if (!curwin)
104 werase(curscr);
105 }
106# ifdef DEBUG
107 fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin);
108 fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
109# endif
110 for (wy = 0; wy < win->_maxy; wy++) {
111# ifdef DEBUG
112 fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy],
113 win->_lastch[wy]);
114# endif
115 if (win->_firstch[wy] != _NOCHANGE)
116 if (makech(win, wy) == ERR)
117 return ERR;
118 else {
119 if (win->_firstch[wy] >= win->_ch_off)
120 win->_firstch[wy] = win->_maxx +
121 win->_ch_off;
122 if (win->_lastch[wy] < win->_maxx +
123 win->_ch_off)
124 win->_lastch[wy] = win->_ch_off;
125 if (win->_lastch[wy] < win->_firstch[wy])
126 win->_firstch[wy] = _NOCHANGE;
127 }
128# ifdef DEBUG
129 fprintf(outf, "\t%d\t%d\n", win->_firstch[wy],
130 win->_lastch[wy]);
131# endif
132 }
133
134 if (win == curscr)
135 domvcur(ly, lx, win->_cury, win->_curx);
136 else {
137 if (win->_leave) {
138 curscr->_cury = ly;
139 curscr->_curx = lx;
140 ly -= win->_begy;
141 lx -= win->_begx;
142 if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
143 lx < win->_maxx) {
144 win->_cury = ly;
145 win->_curx = lx;
146 }
147 else
148 win->_cury = win->_curx = 0;
149 }
150 else {
151 domvcur(ly, lx, win->_cury + win->_begy,
152 win->_curx + win->_begx);
153 curscr->_cury = win->_cury + win->_begy;
154 curscr->_curx = win->_curx + win->_begx;
155 }
156 }
157 retval = OK;
158ret:
159 _win = NULL;
160 fflush(stdout);
161 return retval;
162}
163
164/*
165 * make a change on the screen
166 */
167STATIC
168makech(win, wy)
169reg WINDOW *win;
170short wy;
171{
78ed81a3 172 reg chtype *nsp, *csp, *ce;
15637ed4
RG
173 reg short wx, lch, y;
174 reg int nlsp, clsp; /* last space in lines */
78ed81a3 175 char *ce_tcap;
176 static chtype blank[] = {' ','\0'};
15637ed4
RG
177
178 wx = win->_firstch[wy] - win->_ch_off;
179 if (wx >= win->_maxx)
180 return OK;
181 else if (wx < 0)
182 wx = 0;
183 lch = win->_lastch[wy] - win->_ch_off;
184 if (lch < 0)
185 return OK;
186 else if (lch >= win->_maxx)
187 lch = win->_maxx - 1;;
188 y = wy + win->_begy;
189
190 if (curwin)
78ed81a3 191 csp = blank;
15637ed4
RG
192 else
193 csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
194
195 nsp = &win->_y[wy][wx];
196 if (CE && !curwin) {
197 for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--)
198 if (ce <= win->_y[wy])
199 break;
200 nlsp = ce - win->_y[wy];
201 }
202
203 if (!curwin)
78ed81a3 204 ce_tcap = CE;
15637ed4 205 else
78ed81a3 206 ce_tcap = NULL;
15637ed4
RG
207
208 while (wx <= lch) {
209 if (*nsp != *csp) {
210 domvcur(ly, lx, y, wx + win->_begx);
211# ifdef DEBUG
212 fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx);
213# endif
214 ly = y;
215 lx = wx + win->_begx;
216 while (*nsp != *csp && wx <= lch) {
78ed81a3 217 if (ce_tcap != NULL && wx >= nlsp && *nsp == ' ') {
15637ed4
RG
218 /*
219 * check for clear to end-of-line
220 */
221 ce = &curscr->_y[ly][COLS - 1];
222 while (*ce == ' ')
223 if (ce-- <= csp)
224 break;
225 clsp = ce - curscr->_y[ly] - win->_begx;
226# ifdef DEBUG
227 fprintf(outf, "MAKECH: clsp = %d, nlsp = %d\n", clsp, nlsp);
228# endif
229 if (clsp - nlsp >= strlen(CE)
230 && clsp < win->_maxx) {
231# ifdef DEBUG
232 fprintf(outf, "MAKECH: using CE\n");
233# endif
234 _puts(CE);
235 lx = wx + win->_begx;
236 while (wx++ <= clsp)
237 *csp++ = ' ';
238 return OK;
239 }
78ed81a3 240 ce_tcap = NULL;
15637ed4
RG
241 }
242 /*
243 * enter/exit standout mode as appropriate
244 */
245 if (SO && (*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) {
246 if (*nsp & _STANDOUT) {
247 _puts(SO);
248 curscr->_flags |= _STANDOUT;
249 }
250 else {
251 _puts(SE);
252 curscr->_flags &= ~_STANDOUT;
253 }
254 }
255 wx++;
256 if (wx >= win->_maxx && wy == win->_maxy - 1)
257 if (win->_scroll) {
258 if ((curscr->_flags&_STANDOUT) &&
259 (win->_flags & _ENDLINE))
260 if (!MS) {
261 _puts(SE);
262 curscr->_flags &= ~_STANDOUT;
263 }
264 if (!curwin)
78ed81a3 265 _putchar((*csp = *nsp));
15637ed4 266 else
78ed81a3 267 _putchar(*nsp);
15637ed4
RG
268 if (win->_flags&_FULLWIN && !curwin)
269 scroll(curscr);
270 ly = win->_begy+win->_cury;
271 lx = win->_begx+win->_curx;
272 return OK;
273 }
274 else if (win->_flags&_SCROLLWIN) {
275 lx = --wx;
276 return ERR;
277 }
278 if (!curwin)
78ed81a3 279 _putchar((*csp++ = *nsp));
15637ed4 280 else
78ed81a3 281 _putchar(*nsp);
15637ed4
RG
282# ifdef FULLDEBUG
283 fprintf(outf,
78ed81a3 284 "MAKECH:putchar(%c)\n", *nsp);
15637ed4
RG
285# endif
286 if (UC && (*nsp & _STANDOUT)) {
287 _putchar('\b');
288 _puts(UC);
289 }
290 nsp++;
291 }
292# ifdef DEBUG
293 fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
294# endif
295 if (lx == wx + win->_begx) /* if no change */
296 break;
297 lx = wx + win->_begx;
298 if (lx >= COLS && AM) {
299 lx = 0;
300 ly++;
301 /*
302 * xn glitch: chomps a newline after auto-wrap.
303 * we just feed it now and forget about it.
304 */
305 if (XN) {
306 _putchar('\n');
307 _putchar('\r');
308 }
309 }
310 }
311 else if (wx <= lch)
312 while (*nsp == *csp && wx <= lch) {
313 nsp++;
314 if (!curwin)
315 csp++;
316 ++wx;
317 }
318 else
319 break;
320# ifdef DEBUG
321 fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
322# endif
323 }
324 return OK;
325}
326
327/*
328 * perform a mvcur, leaving standout mode if necessary
329 */
330STATIC
331domvcur(oy, ox, ny, nx)
332int oy, ox, ny, nx; {
333
334 if (curscr->_flags & _STANDOUT && !MS) {
335 _puts(SE);
336 curscr->_flags &= ~_STANDOUT;
337 }
338 mvcur(oy, ox, ny, nx);
339}