xref: /csrg-svn/lib/libcurses/refresh.c (revision 56238)
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*56238Selan static char sccsid[] = "@(#)refresh.c	5.9 (Berkeley) 09/14/92";
1034677Sbostic #endif /* not lint */
1122791Smckusick 
1255976Sbostic #include <curses.h>
1355986Sbostic #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 
44*56238Selan 	ly = curscr->cury;
45*56238Selan 	lx = curscr->curx;
462287Sarnold 	wy = 0;
472287Sarnold 	_win = win;
482287Sarnold 	curwin = (win == curscr);
492287Sarnold 
50*56238Selan 	if (win->flags & __CLEAROK || curscr->flags & __CLEAROK || curwin) {
51*56238Selan 		if ((win->flags & __FULLWIN) || curscr->flags & __CLEAROK) {
5255976Sbostic 			tputs(CL, 0, __cputchar);
5312358Sarnold 			ly = 0;
5412358Sarnold 			lx = 0;
5512358Sarnold 			if (!curwin) {
56*56238Selan 				curscr->flags &= ~__CLEAROK;
57*56238Selan 				curscr->cury = 0;
58*56238Selan 				curscr->curx = 0;
592287Sarnold 				werase(curscr);
6012358Sarnold 			}
612261Sarnold 			touchwin(win);
622261Sarnold 		}
63*56238Selan 		win->flags &= ~__CLEAROK;
642261Sarnold 	}
652261Sarnold 	if (!CA) {
66*56238Selan 		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
75*56238Selan 	for (wy = 0; wy < win->maxy; wy++) {
7655976Sbostic #ifdef DEBUG
7755976Sbostic 		__TRACE("%d\t%d\t%d\n",
78*56238Selan 		    wy, win->lines[wy]->firstch, win->lines[wy]->lastch);
7955976Sbostic #endif
80*56238Selan 		if (win->lines[wy]->flags & __ISDIRTY)
812261Sarnold 			if (makech(win, wy) == ERR)
8255976Sbostic 				return (ERR);
8319893Sbloom 			else {
84*56238Selan 				if (win->lines[wy]->firstch >= win->ch_off)
85*56238Selan 					win->lines[wy]->firstch = win->maxx +
86*56238Selan 					    win->ch_off;
87*56238Selan 				if (win->lines[wy]->lastch < win->maxx +
88*56238Selan 				    win->ch_off)
89*56238Selan 					win->lines[wy]->lastch = win->ch_off;
90*56238Selan 				if (win->lines[wy]->lastch <
91*56238Selan 				    win->lines[wy]->firstch)
92*56238Selan 					win->lines[wy]->flags &= ~__ISDIRTY;
9319893Sbloom 			}
9455976Sbostic #ifdef DEBUG
95*56238Selan 		__TRACE("\t%d\t%d\n", win->lines[wy]->firstch,
96*56238Selan 			win->lines[wy]->lastch);
9755976Sbostic #endif
982261Sarnold 	}
99*56238Selan 
100*56238Selan 	__TRACE("refresh: ly=%d, lx=%d\n", ly, lx);
10112358Sarnold 	if (win == curscr)
102*56238Selan 		domvcur(ly, lx, win->cury, win->curx);
10319893Sbloom 	else {
104*56238Selan 		if (win->flags & __LEAVEOK) {
105*56238Selan 			curscr->cury = ly;
106*56238Selan 			curscr->curx = lx;
107*56238Selan 			ly -= win->begy;
108*56238Selan 			lx -= win->begx;
109*56238Selan 			if (ly >= 0 && ly < win->maxy && lx >= 0 &&
110*56238Selan 			    lx < win->maxx) {
111*56238Selan 				win->cury = ly;
112*56238Selan 				win->curx = lx;
11355976Sbostic 			} else
114*56238Selan 				win->cury = win->curx = 0;
11555976Sbostic 		} else {
116*56238Selan 			domvcur(ly, lx, win->cury + win->begy,
117*56238Selan 			    win->curx + win->begx);
118*56238Selan 			curscr->cury = win->cury + win->begy;
119*56238Selan 			curscr->curx = win->curx + win->begx;
12019893Sbloom 		}
1212261Sarnold 	}
1222287Sarnold 	retval = OK;
12355986Sbostic 
1242261Sarnold 	_win = NULL;
12555976Sbostic 	(void)fflush(stdout);
12655976Sbostic 	return (retval);
1272261Sarnold }
1282261Sarnold 
1292261Sarnold /*
13055976Sbostic  * makech --
13155976Sbostic  *	Make a change on the screen.
1322261Sarnold  */
13355976Sbostic static int
1342261Sarnold makech(win, wy)
13555976Sbostic 	register WINDOW *win;
13655976Sbostic 	int wy;
1372261Sarnold {
13855976Sbostic 	register int nlsp, clsp;		/* Last space in lines. */
13955976Sbostic 	register short wx, lch, y;
14055976Sbostic 	register char *nsp, *csp, *ce;
1412261Sarnold 
142*56238Selan 	if (!(win->lines[wy]->flags & __ISDIRTY))
14355976Sbostic 		return (OK);
144*56238Selan 	wx = win->lines[wy]->firstch - win->ch_off;
145*56238Selan 	if (wx >= win->maxx)
146*56238Selan 		return (OK);
14719893Sbloom 	else if (wx < 0)
14819893Sbloom 		wx = 0;
149*56238Selan 	lch = win->lines[wy]->lastch - win->ch_off;
15019893Sbloom 	if (lch < 0)
15155976Sbostic 		return (OK);
152*56238Selan 	else if (lch >= win->maxx)
153*56238Selan 		lch = win->maxx - 1;
154*56238Selan 	y = wy + win->begy;
15519893Sbloom 
1562287Sarnold 	if (curwin)
1572287Sarnold 		csp = " ";
1582287Sarnold 	else
159*56238Selan 		csp = &curscr->lines[wy + win->begy]->line[wx + win->begx];
16019893Sbloom 
161*56238Selan 	nsp = &win->lines[wy]->line[wx];
1622287Sarnold 	if (CE && !curwin) {
163*56238Selan 		for (ce = &win->lines[wy]->line[win->maxx - 1];
164*56238Selan 		     *ce == ' '; ce--)
165*56238Selan 			if (ce <= win->lines[wy]->line)
1662261Sarnold 				break;
167*56238Selan 		nlsp = ce - win->lines[wy]->line;
1682261Sarnold 	}
1692287Sarnold 	if (!curwin)
1702287Sarnold 		ce = CE;
1712287Sarnold 	else
1722287Sarnold 		ce = NULL;
17319893Sbloom 
1742261Sarnold 	while (wx <= lch) {
17555986Sbostic 		if (*nsp == *csp) {
17655986Sbostic 			if (wx <= lch) {
17755986Sbostic 				while (*nsp == *csp && wx <= lch) {
17855986Sbostic 					nsp++;
17955986Sbostic 					if (!curwin)
18055986Sbostic 						csp++;
18155986Sbostic 					++wx;
18255986Sbostic 				}
18355986Sbostic 				continue;
18455986Sbostic 			}
18555986Sbostic 			break;
18655986Sbostic 		}
187*56238Selan 		domvcur(ly, lx, y, wx + win->begx);
18855976Sbostic #ifdef DEBUG
18956114Selan 		__TRACE("makech: 1: wx = %d, lx = %d, newy = %d, newx = %d\n",
190*56238Selan 		    wx, lx, y, wx + win->begx);
19155976Sbostic #endif
19255986Sbostic 		ly = y;
193*56238Selan 		lx = wx + win->begx;
19455986Sbostic 		while (*nsp != *csp && wx <= lch) {
19555986Sbostic 			if (ce != NULL && wx >= nlsp && *nsp == ' ') {
19655986Sbostic 				/* Check for clear to end-of-line. */
197*56238Selan 				ce = &curscr->lines[ly]->line[COLS - 1];
19855986Sbostic 				while (*ce == ' ')
19955986Sbostic 					if (ce-- <= csp)
20055986Sbostic 						break;
201*56238Selan 				clsp = ce - curscr->lines[ly]->line -
202*56238Selan 				       win->begx;
20355976Sbostic #ifdef DEBUG
20455986Sbostic 			__TRACE("makech: clsp = %d, nlsp = %d\n", clsp, nlsp);
20555976Sbostic #endif
20655986Sbostic 				if (clsp - nlsp >= strlen(CE) &&
207*56238Selan 				    clsp < win->maxx) {
20855976Sbostic #ifdef DEBUG
20955986Sbostic 					__TRACE("makech: using CE\n");
21055976Sbostic #endif
21155986Sbostic 					tputs(CE, 0, __cputchar);
212*56238Selan 					lx = wx + win->begx;
21355986Sbostic 					while (wx++ <= clsp)
21455986Sbostic 						*csp++ = ' ';
21555986Sbostic 					return (OK);
2162261Sarnold 				}
21755986Sbostic 				ce = NULL;
21855986Sbostic 			}
21955986Sbostic 
22055986Sbostic 			/* Enter/exit standout mode as appropriate. */
221*56238Selan 			if (SO && (*nsp & __STANDOUT) !=
222*56238Selan 			    (curscr->flags & __STANDOUT)) {
223*56238Selan 				if (*nsp & __STANDOUT) {
22455986Sbostic 					tputs(SO, 0, __cputchar);
225*56238Selan 					curscr->flags |= __WSTANDOUT;
22655986Sbostic 				} else {
22755986Sbostic 					tputs(SE, 0, __cputchar);
228*56238Selan 					curscr->flags &= ~__WSTANDOUT;
2292261Sarnold 				}
23055986Sbostic 			}
23155986Sbostic 
23255986Sbostic 			wx++;
233*56238Selan 			if (wx >= win->maxx && wy == win->maxy - 1)
234*56238Selan 				if (win->flags & __SCROLLOK) {
235*56238Selan 					if (curscr->flags & __WSTANDOUT
236*56238Selan 					    && win->flags & __ENDLINE)
23755986Sbostic 						if (!MS) {
23855986Sbostic 							tputs(SE, 0,
23955986Sbostic 							    __cputchar);
240*56238Selan 							curscr->flags &=
241*56238Selan 							    ~__WSTANDOUT;
24255976Sbostic 						}
24355986Sbostic 					if (!curwin)
24455986Sbostic 						putchar((*csp = *nsp) & 0177);
24555986Sbostic 					else
24655986Sbostic 						putchar(*nsp & 0177);
247*56238Selan 					if (win->flags & __FULLWIN && !curwin)
24855986Sbostic 						scroll(curscr);
249*56238Selan 					ly = win->begy + wy;
250*56238Selan 					lx = win->begx + wx;
25155986Sbostic 					return (OK);
25255986Sbostic 				} else
253*56238Selan 					if (win->flags & __SCROLLWIN) {
25455986Sbostic 						lx = --wx;
25555986Sbostic 						return (ERR);
25655986Sbostic 					}
25755986Sbostic 			if (!curwin)
25855986Sbostic 				putchar((*csp++ = *nsp) & 0177);
25955986Sbostic 			else
26055986Sbostic 				putchar(*nsp & 0177);
26155976Sbostic #ifdef DEBUG
26255986Sbostic 			__TRACE("makech: putchar(%c)\n", *nsp & 0177);
26355976Sbostic #endif
264*56238Selan 			if (UC && (*nsp & __STANDOUT)) {
26555986Sbostic 				putchar('\b');
26655986Sbostic 				tputs(UC, 0, __cputchar);
2672261Sarnold 			}
26855986Sbostic 			nsp++;
26955986Sbostic 		}
27055976Sbostic #ifdef DEBUG
27155986Sbostic 		__TRACE("makech: 2: wx = %d, lx = %d\n", wx, lx);
27255976Sbostic #endif
273*56238Selan 		if (lx == wx + win->begx)	/* If no change. */
27455986Sbostic 			break;
275*56238Selan 		lx = wx + win->begx;
27655986Sbostic 		if (lx >= COLS && AM) {
27755986Sbostic 			lx = 0;
27855986Sbostic 			ly++;
27955986Sbostic 			/*
28055986Sbostic 			 * xn glitch: chomps a newline after auto-wrap.
28155986Sbostic 			 * we just feed it now and forget about it.
28255986Sbostic 			 */
28355986Sbostic 			if (XN) {
28455986Sbostic 				putchar('\n');
28555986Sbostic 				putchar('\r');
28622789Smckusick 			}
28755986Sbostic 		}
28855976Sbostic #ifdef DEBUG
28955976Sbostic 		__TRACE("makech: 3: wx = %d, lx = %d\n", wx, lx);
29055976Sbostic #endif
2912261Sarnold 	}
29255976Sbostic 	return (OK);
29311736Sarnold }
29411736Sarnold 
29511736Sarnold /*
29655976Sbostic  * domvcur --
29755976Sbostic  *	Do a mvcur, leaving standout mode if necessary.
29811736Sarnold  */
29955976Sbostic static void
30011736Sarnold domvcur(oy, ox, ny, nx)
30155976Sbostic 	int oy, ox, ny, nx;
30255976Sbostic {
303*56238Selan 	if (curscr->flags & __WSTANDOUT && !MS) {
30455976Sbostic 		tputs(SE, 0, __cputchar);
305*56238Selan 		curscr->flags &= ~__WSTANDOUT;
3062261Sarnold 	}
30711736Sarnold 	mvcur(oy, ox, ny, nx);
3082261Sarnold }
309