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