xref: /csrg-svn/lib/libcurses/refresh.c (revision 55986)
12261Sarnold /*
234677Sbostic  * Copyright (c) 1981 Regents of the University of California.
334677Sbostic  * All rights reserved.
434677Sbostic  *
542657Sbostic  * %sccs.include.redist.c%
622791Smckusick  */
722791Smckusick 
822791Smckusick #ifndef lint
9*55986Sbostic static char sccsid[] = "@(#)refresh.c	5.7 (Berkeley) 08/23/92";
1034677Sbostic #endif /* not lint */
1122791Smckusick 
1255976Sbostic #include <curses.h>
13*55986Sbostic #include <string.h>
142261Sarnold 
1555976Sbostic static int curwin;
1655976Sbostic static short ly, lx;
172261Sarnold 
1855976Sbostic WINDOW *_win;
192261Sarnold 
2055976Sbostic static void	domvcur __P((int, int, int, int));
2155976Sbostic static int	makech __P((WINDOW *, int));
222287Sarnold 
2355976Sbostic /*
2455976Sbostic  * wrefresh --
2555976Sbostic  *	Make the current screen look like "win" over the area coverd by
2655976Sbostic  *	win.
2755976Sbostic  */
2855976Sbostic int
292261Sarnold wrefresh(win)
3055976Sbostic 	register WINDOW *win;
312261Sarnold {
3255976Sbostic 	register int retval;
3355976Sbostic 	register short wy;
342261Sarnold 
3555976Sbostic 	/* Make sure were in visual state. */
3655976Sbostic 	if (__endwin) {
3755976Sbostic 		tputs(VS, 0, __cputchar);
3855976Sbostic 		tputs(TI, 0, __cputchar);
3955976Sbostic 		__endwin = 0;
402261Sarnold 	}
412287Sarnold 
4255976Sbostic 	/* Initialize loop parameters. */
432287Sarnold 
442287Sarnold 	ly = curscr->_cury;
452287Sarnold 	lx = curscr->_curx;
462287Sarnold 	wy = 0;
472287Sarnold 	_win = win;
482287Sarnold 	curwin = (win == curscr);
492287Sarnold 
502287Sarnold 	if (win->_clear || curscr->_clear || curwin) {
512261Sarnold 		if ((win->_flags & _FULLWIN) || curscr->_clear) {
5255976Sbostic 			tputs(CL, 0, __cputchar);
5312358Sarnold 			ly = 0;
5412358Sarnold 			lx = 0;
5512358Sarnold 			if (!curwin) {
5655976Sbostic 				curscr->_clear = 0;
5712358Sarnold 				curscr->_cury = 0;
5812358Sarnold 				curscr->_curx = 0;
592287Sarnold 				werase(curscr);
6012358Sarnold 			}
612261Sarnold 			touchwin(win);
622261Sarnold 		}
6355976Sbostic 		win->_clear = 0;
642261Sarnold 	}
652261Sarnold 	if (!CA) {
662261Sarnold 		if (win->_curx != 0)
6755976Sbostic 			putchar('\n');
682287Sarnold 		if (!curwin)
692287Sarnold 			werase(curscr);
702261Sarnold 	}
7155976Sbostic #ifdef DEBUG
7255976Sbostic 	__TRACE("wrefresh: (%0.2o): curwin = %d\n", win, curwin);
7355976Sbostic 	__TRACE("wrefresh: \tfirstch\tlastch\n");
7455976Sbostic #endif
752261Sarnold 	for (wy = 0; wy < win->_maxy; wy++) {
7655976Sbostic #ifdef DEBUG
7755976Sbostic 		__TRACE("%d\t%d\t%d\n",
7855976Sbostic 		    wy, win->_firstch[wy], win->_lastch[wy]);
7955976Sbostic #endif
802261Sarnold 		if (win->_firstch[wy] != _NOCHANGE)
812261Sarnold 			if (makech(win, wy) == ERR)
8255976Sbostic 				return (ERR);
8319893Sbloom 			else {
8419893Sbloom 				if (win->_firstch[wy] >= win->_ch_off)
8519893Sbloom 					win->_firstch[wy] = win->_maxx +
8655976Sbostic 					    win->_ch_off;
8719893Sbloom 				if (win->_lastch[wy] < win->_maxx +
8855976Sbostic 				    win->_ch_off)
8919893Sbloom 					win->_lastch[wy] = win->_ch_off;
9019893Sbloom 				if (win->_lastch[wy] < win->_firstch[wy])
9119893Sbloom 					win->_firstch[wy] = _NOCHANGE;
9219893Sbloom 			}
9355976Sbostic #ifdef DEBUG
9455976Sbostic 		__TRACE("\t%d\t%d\n", win->_firstch[wy], win->_lastch[wy]);
9555976Sbostic #endif
962261Sarnold 	}
9719893Sbloom 
9812358Sarnold 	if (win == curscr)
9912358Sarnold 		domvcur(ly, lx, win->_cury, win->_curx);
10019893Sbloom 	else {
10119893Sbloom 		if (win->_leave) {
10219893Sbloom 			curscr->_cury = ly;
10319893Sbloom 			curscr->_curx = lx;
10419893Sbloom 			ly -= win->_begy;
10519893Sbloom 			lx -= win->_begx;
10619893Sbloom 			if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
10719893Sbloom 			    lx < win->_maxx) {
10819893Sbloom 				win->_cury = ly;
10919893Sbloom 				win->_curx = lx;
11055976Sbostic 			} else
11119893Sbloom 				win->_cury = win->_curx = 0;
11255976Sbostic 		} else {
11319893Sbloom 			domvcur(ly, lx, win->_cury + win->_begy,
11455976Sbostic 			    win->_curx + win->_begx);
11519893Sbloom 			curscr->_cury = win->_cury + win->_begy;
11619893Sbloom 			curscr->_curx = win->_curx + win->_begx;
11719893Sbloom 		}
1182261Sarnold 	}
1192287Sarnold 	retval = OK;
120*55986Sbostic 
1212261Sarnold 	_win = NULL;
12255976Sbostic 	(void)fflush(stdout);
12355976Sbostic 	return (retval);
1242261Sarnold }
1252261Sarnold 
1262261Sarnold /*
12755976Sbostic  * makech --
12855976Sbostic  *	Make a change on the screen.
1292261Sarnold  */
13055976Sbostic static int
1312261Sarnold makech(win, wy)
13255976Sbostic 	register WINDOW *win;
13355976Sbostic 	int wy;
1342261Sarnold {
13555976Sbostic 	register int nlsp, clsp;		/* Last space in lines. */
13655976Sbostic 	register short wx, lch, y;
13755976Sbostic 	register char *nsp, *csp, *ce;
1382261Sarnold 
13919893Sbloom 	wx = win->_firstch[wy] - win->_ch_off;
14019893Sbloom 	if (wx >= win->_maxx)
14155976Sbostic 		return (OK);
14219893Sbloom 	else if (wx < 0)
14319893Sbloom 		wx = 0;
14419893Sbloom 	lch = win->_lastch[wy] - win->_ch_off;
14519893Sbloom 	if (lch < 0)
14655976Sbostic 		return (OK);
14719893Sbloom 	else if (lch >= win->_maxx)
14819893Sbloom 		lch = win->_maxx - 1;;
1492261Sarnold 	y = wy + win->_begy;
15019893Sbloom 
1512287Sarnold 	if (curwin)
1522287Sarnold 		csp = " ";
1532287Sarnold 	else
1542287Sarnold 		csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
15519893Sbloom 
1562261Sarnold 	nsp = &win->_y[wy][wx];
1572287Sarnold 	if (CE && !curwin) {
1582261Sarnold 		for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--)
1592261Sarnold 			if (ce <= win->_y[wy])
1602261Sarnold 				break;
1612261Sarnold 		nlsp = ce - win->_y[wy];
1622261Sarnold 	}
1632287Sarnold 	if (!curwin)
1642287Sarnold 		ce = CE;
1652287Sarnold 	else
1662287Sarnold 		ce = NULL;
16719893Sbloom 
1682261Sarnold 	while (wx <= lch) {
169*55986Sbostic 		if (*nsp == *csp) {
170*55986Sbostic 			if (wx <= lch) {
171*55986Sbostic 				while (*nsp == *csp && wx <= lch) {
172*55986Sbostic 					nsp++;
173*55986Sbostic 					if (!curwin)
174*55986Sbostic 						csp++;
175*55986Sbostic 					++wx;
176*55986Sbostic 				}
177*55986Sbostic 				continue;
178*55986Sbostic 			}
179*55986Sbostic 			break;
180*55986Sbostic 		}
181*55986Sbostic 		domvcur(ly, lx, y, wx + win->_begx);
18255976Sbostic #ifdef DEBUG
183*55986Sbostic 		__TRACE("makech: 1: wx = %d, lx = %d\n", wx, lx);
18455976Sbostic #endif
185*55986Sbostic 		ly = y;
186*55986Sbostic 		lx = wx + win->_begx;
187*55986Sbostic 		while (*nsp != *csp && wx <= lch) {
188*55986Sbostic 			if (ce != NULL && wx >= nlsp && *nsp == ' ') {
189*55986Sbostic 				/* Check for clear to end-of-line. */
190*55986Sbostic 				ce = &curscr->_y[ly][COLS - 1];
191*55986Sbostic 				while (*ce == ' ')
192*55986Sbostic 					if (ce-- <= csp)
193*55986Sbostic 						break;
194*55986Sbostic 				clsp = ce - curscr->_y[ly] - win->_begx;
19555976Sbostic #ifdef DEBUG
196*55986Sbostic 			__TRACE("makech: clsp = %d, nlsp = %d\n", clsp, nlsp);
19755976Sbostic #endif
198*55986Sbostic 				if (clsp - nlsp >= strlen(CE) &&
199*55986Sbostic 				    clsp < win->_maxx) {
20055976Sbostic #ifdef DEBUG
201*55986Sbostic 					__TRACE("makech: using CE\n");
20255976Sbostic #endif
203*55986Sbostic 					tputs(CE, 0, __cputchar);
204*55986Sbostic 					lx = wx + win->_begx;
205*55986Sbostic 					while (wx++ <= clsp)
206*55986Sbostic 						*csp++ = ' ';
207*55986Sbostic 					return (OK);
2082261Sarnold 				}
209*55986Sbostic 				ce = NULL;
210*55986Sbostic 			}
211*55986Sbostic 
212*55986Sbostic 			/* Enter/exit standout mode as appropriate. */
213*55986Sbostic 			if (SO && (*nsp & _STANDOUT) !=
214*55986Sbostic 			    (curscr->_flags & _STANDOUT)) {
215*55986Sbostic 				if (*nsp & _STANDOUT) {
216*55986Sbostic 					tputs(SO, 0, __cputchar);
217*55986Sbostic 					curscr->_flags |= _STANDOUT;
218*55986Sbostic 				} else {
219*55986Sbostic 					tputs(SE, 0, __cputchar);
220*55986Sbostic 					curscr->_flags &= ~_STANDOUT;
2212261Sarnold 				}
222*55986Sbostic 			}
223*55986Sbostic 
224*55986Sbostic 			wx++;
225*55986Sbostic 			if (wx >= win->_maxx && wy == win->_maxy - 1)
226*55986Sbostic 				if (win->_scroll) {
227*55986Sbostic 					if (curscr->_flags & _STANDOUT
228*55986Sbostic 					    && win->_flags & _ENDLINE)
229*55986Sbostic 						if (!MS) {
230*55986Sbostic 							tputs(SE, 0,
231*55986Sbostic 							    __cputchar);
232*55986Sbostic 							curscr->_flags &=
233*55986Sbostic 							    ~_STANDOUT;
23455976Sbostic 						}
235*55986Sbostic 					if (!curwin)
236*55986Sbostic 						putchar((*csp = *nsp) & 0177);
237*55986Sbostic 					else
238*55986Sbostic 						putchar(*nsp & 0177);
239*55986Sbostic 					if (win->_flags & _FULLWIN && !curwin)
240*55986Sbostic 						scroll(curscr);
241*55986Sbostic 					ly = win->_begy + win->_cury;
242*55986Sbostic 					lx = win->_begx + win->_curx;
243*55986Sbostic 					return (OK);
244*55986Sbostic 				} else
245*55986Sbostic 					if (win->_flags & _SCROLLWIN) {
246*55986Sbostic 						lx = --wx;
247*55986Sbostic 						return (ERR);
248*55986Sbostic 					}
249*55986Sbostic 			if (!curwin)
250*55986Sbostic 				putchar((*csp++ = *nsp) & 0177);
251*55986Sbostic 			else
252*55986Sbostic 				putchar(*nsp & 0177);
25355976Sbostic #ifdef DEBUG
254*55986Sbostic 			__TRACE("makech: putchar(%c)\n", *nsp & 0177);
25555976Sbostic #endif
256*55986Sbostic 			if (UC && (*nsp & _STANDOUT)) {
257*55986Sbostic 				putchar('\b');
258*55986Sbostic 				tputs(UC, 0, __cputchar);
2592261Sarnold 			}
260*55986Sbostic 			nsp++;
261*55986Sbostic 		}
26255976Sbostic #ifdef DEBUG
263*55986Sbostic 		__TRACE("makech: 2: wx = %d, lx = %d\n", wx, lx);
26455976Sbostic #endif
265*55986Sbostic 		if (lx == wx + win->_begx)	/* If no change. */
266*55986Sbostic 			break;
267*55986Sbostic 		lx = wx + win->_begx;
268*55986Sbostic 		if (lx >= COLS && AM) {
269*55986Sbostic 			lx = 0;
270*55986Sbostic 			ly++;
271*55986Sbostic 			/*
272*55986Sbostic 			 * xn glitch: chomps a newline after auto-wrap.
273*55986Sbostic 			 * we just feed it now and forget about it.
274*55986Sbostic 			 */
275*55986Sbostic 			if (XN) {
276*55986Sbostic 				putchar('\n');
277*55986Sbostic 				putchar('\r');
27822789Smckusick 			}
279*55986Sbostic 		}
28055976Sbostic #ifdef DEBUG
28155976Sbostic 		__TRACE("makech: 3: wx = %d, lx = %d\n", wx, lx);
28255976Sbostic #endif
2832261Sarnold 	}
28455976Sbostic 	return (OK);
28511736Sarnold }
28611736Sarnold 
28711736Sarnold /*
28855976Sbostic  * domvcur --
28955976Sbostic  *	Do a mvcur, leaving standout mode if necessary.
29011736Sarnold  */
29155976Sbostic static void
29211736Sarnold domvcur(oy, ox, ny, nx)
29355976Sbostic 	int oy, ox, ny, nx;
29455976Sbostic {
29511736Sarnold 	if (curscr->_flags & _STANDOUT && !MS) {
29655976Sbostic 		tputs(SE, 0, __cputchar);
29711736Sarnold 		curscr->_flags &= ~_STANDOUT;
2982261Sarnold 	}
29911736Sarnold 	mvcur(oy, ox, ny, nx);
3002261Sarnold }
301