xref: /original-bsd/lib/libcurses/refresh.c (revision 42ef0c70)
1 /*
2  * make the current screen look like "win" over the area coverd by
3  * win.
4  *
5  * 02/17/82 (Berkeley) @(#)refresh.c	1.5
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 		mvcur(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 			mvcur(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 ((win->_flags&(_ENDLINE|_STANDOUT)) == (_ENDLINE|_STANDOUT))
183 						if (!MS) {
184 						    _puts(SE);
185 						    win->_flags &= ~_STANDOUT;
186 						}
187 					    if (!curwin)
188 						putchar((*csp = *nsp) & 0177);
189 					    else
190 						putchar(*nsp & 0177);
191 					    scroll(win);
192 					    if (win->_flags&_FULLWIN && !curwin)
193 						scroll(curscr);
194 					    ly = win->_begy+win->_cury;
195 					    lx = win->_begx+win->_curx;
196 					    return OK;
197 					}
198 					else if (win->_flags&_SCROLLWIN) {
199 					    lx = --wx;
200 					    return ERR;
201 					}
202 				if (!curwin)
203 					putchar((*csp++ = *nsp) & 0177);
204 				else
205 					putchar(*nsp & 0177);
206 				if (UC && (*nsp & _STANDOUT)) {
207 					putchar('\b');
208 					_puts(UC);
209 				}
210 				nsp++;
211 			}
212 			if (!MS && (*nsp & _STANDOUT)  && (*csp & _STANDOUT)) {
213 				_puts(SE);
214 				win->_flags &= ~_STANDOUT;
215 			}
216 # ifdef DEBUG
217 			fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
218 # endif
219 			if (lx == wx + win->_begx)	/* if no change */
220 				break;
221 			lx = wx + win->_begx;
222 		}
223 		else if (wx < lch)
224 			while (*nsp == *csp) {
225 				nsp++;
226 				if (!curwin)
227 					csp++;
228 				++wx;
229 			}
230 		else
231 			break;
232 # ifdef DEBUG
233 		fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
234 # endif
235 	}
236 ret:
237 	if ((win->_flags & _STANDOUT) && !MS) {
238 		_puts(SE);
239 		win->_flags &= ~_STANDOUT;
240 	}
241 	return OK;
242 }
243