xref: /csrg-svn/lib/libcurses/refresh.c (revision 34677)
12261Sarnold /*
2*34677Sbostic  * Copyright (c) 1981 Regents of the University of California.
3*34677Sbostic  * All rights reserved.
4*34677Sbostic  *
5*34677Sbostic  * Redistribution and use in source and binary forms are permitted
6*34677Sbostic  * provided that this notice is preserved and that due credit is given
7*34677Sbostic  * to the University of California at Berkeley. The name of the University
8*34677Sbostic  * may not be used to endorse or promote products derived from this
9*34677Sbostic  * software without specific prior written permission. This software
10*34677Sbostic  * is provided ``as is'' without express or implied warranty.
1122791Smckusick  */
1222791Smckusick 
1322791Smckusick #ifndef lint
14*34677Sbostic static char sccsid[] = "@(#)refresh.c	5.2 (Berkeley) 06/08/88";
15*34677Sbostic #endif /* not lint */
1622791Smckusick 
1722791Smckusick /*
182261Sarnold  * make the current screen look like "win" over the area coverd by
192261Sarnold  * win.
202261Sarnold  */
212261Sarnold 
222261Sarnold # include	"curses.ext"
232261Sarnold 
242287Sarnold # ifdef DEBUG
252287Sarnold # define	STATIC
262261Sarnold # else
272287Sarnold # define	STATIC	static
282261Sarnold # endif
292261Sarnold 
302287Sarnold STATIC short	ly, lx;
312287Sarnold 
322287Sarnold STATIC bool	curwin;
332287Sarnold 
342261Sarnold WINDOW	*_win = NULL;
352261Sarnold 
362261Sarnold wrefresh(win)
372261Sarnold reg WINDOW	*win;
382261Sarnold {
392261Sarnold 	reg short	wy;
402287Sarnold 	reg int		retval;
4119893Sbloom 	reg WINDOW	*orig;
422261Sarnold 
432261Sarnold 	/*
442261Sarnold 	 * make sure were in visual state
452261Sarnold 	 */
462261Sarnold 	if (_endwin) {
472261Sarnold 		_puts(VS);
482261Sarnold 		_puts(TI);
492261Sarnold 		_endwin = FALSE;
502261Sarnold 	}
512287Sarnold 
522287Sarnold 	/*
532287Sarnold 	 * initialize loop parameters
542287Sarnold 	 */
552287Sarnold 
562287Sarnold 	ly = curscr->_cury;
572287Sarnold 	lx = curscr->_curx;
582287Sarnold 	wy = 0;
592287Sarnold 	_win = win;
602287Sarnold 	curwin = (win == curscr);
612287Sarnold 
622287Sarnold 	if (win->_clear || curscr->_clear || curwin) {
632261Sarnold 		if ((win->_flags & _FULLWIN) || curscr->_clear) {
642261Sarnold 			_puts(CL);
6512358Sarnold 			ly = 0;
6612358Sarnold 			lx = 0;
6712358Sarnold 			if (!curwin) {
6812358Sarnold 				curscr->_clear = FALSE;
6912358Sarnold 				curscr->_cury = 0;
7012358Sarnold 				curscr->_curx = 0;
712287Sarnold 				werase(curscr);
7212358Sarnold 			}
732261Sarnold 			touchwin(win);
742261Sarnold 		}
752261Sarnold 		win->_clear = FALSE;
762261Sarnold 	}
772261Sarnold 	if (!CA) {
782261Sarnold 		if (win->_curx != 0)
7919893Sbloom 			_putchar('\n');
802287Sarnold 		if (!curwin)
812287Sarnold 			werase(curscr);
822261Sarnold 	}
832261Sarnold # ifdef DEBUG
842287Sarnold 	fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin);
852261Sarnold 	fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
862261Sarnold # endif
872261Sarnold 	for (wy = 0; wy < win->_maxy; wy++) {
882261Sarnold # ifdef DEBUG
8919893Sbloom 		fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy],
9019893Sbloom 			win->_lastch[wy]);
912261Sarnold # endif
922261Sarnold 		if (win->_firstch[wy] != _NOCHANGE)
932261Sarnold 			if (makech(win, wy) == ERR)
942261Sarnold 				return ERR;
9519893Sbloom 			else {
9619893Sbloom 				if (win->_firstch[wy] >= win->_ch_off)
9719893Sbloom 					win->_firstch[wy] = win->_maxx +
9819893Sbloom 							    win->_ch_off;
9919893Sbloom 				if (win->_lastch[wy] < win->_maxx +
10019893Sbloom 						       win->_ch_off)
10119893Sbloom 					win->_lastch[wy] = win->_ch_off;
10219893Sbloom 				if (win->_lastch[wy] < win->_firstch[wy])
10319893Sbloom 					win->_firstch[wy] = _NOCHANGE;
10419893Sbloom 			}
10519893Sbloom # ifdef DEBUG
10619893Sbloom 		fprintf(outf, "\t%d\t%d\n", win->_firstch[wy],
10719893Sbloom 			win->_lastch[wy]);
10819893Sbloom # endif
1092261Sarnold 	}
11019893Sbloom 
11112358Sarnold 	if (win == curscr)
11212358Sarnold 		domvcur(ly, lx, win->_cury, win->_curx);
11319893Sbloom 	else {
11419893Sbloom 		if (win->_leave) {
11519893Sbloom 			curscr->_cury = ly;
11619893Sbloom 			curscr->_curx = lx;
11719893Sbloom 			ly -= win->_begy;
11819893Sbloom 			lx -= win->_begx;
11919893Sbloom 			if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
12019893Sbloom 			    lx < win->_maxx) {
12119893Sbloom 				win->_cury = ly;
12219893Sbloom 				win->_curx = lx;
12319893Sbloom 			}
12419893Sbloom 			else
12519893Sbloom 				win->_cury = win->_curx = 0;
1262261Sarnold 		}
12719893Sbloom 		else {
12819893Sbloom 			domvcur(ly, lx, win->_cury + win->_begy,
12919893Sbloom 				win->_curx + win->_begx);
13019893Sbloom 			curscr->_cury = win->_cury + win->_begy;
13119893Sbloom 			curscr->_curx = win->_curx + win->_begx;
13219893Sbloom 		}
1332261Sarnold 	}
1342287Sarnold 	retval = OK;
1352287Sarnold ret:
1362261Sarnold 	_win = NULL;
1372261Sarnold 	fflush(stdout);
1382287Sarnold 	return retval;
1392261Sarnold }
1402261Sarnold 
1412261Sarnold /*
1422261Sarnold  * make a change on the screen
1432261Sarnold  */
1442287Sarnold STATIC
1452261Sarnold makech(win, wy)
1462261Sarnold reg WINDOW	*win;
1472261Sarnold short		wy;
1482261Sarnold {
1492261Sarnold 	reg char	*nsp, *csp, *ce;
1502261Sarnold 	reg short	wx, lch, y;
1512261Sarnold 	reg int		nlsp, clsp;	/* last space in lines		*/
1522261Sarnold 
15319893Sbloom 	wx = win->_firstch[wy] - win->_ch_off;
15419893Sbloom 	if (wx >= win->_maxx)
15519893Sbloom 		return OK;
15619893Sbloom 	else if (wx < 0)
15719893Sbloom 		wx = 0;
15819893Sbloom 	lch = win->_lastch[wy] - win->_ch_off;
15919893Sbloom 	if (lch < 0)
16019893Sbloom 		return OK;
16119893Sbloom 	else if (lch >= win->_maxx)
16219893Sbloom 		lch = win->_maxx - 1;;
1632261Sarnold 	y = wy + win->_begy;
16419893Sbloom 
1652287Sarnold 	if (curwin)
1662287Sarnold 		csp = " ";
1672287Sarnold 	else
1682287Sarnold 		csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
16919893Sbloom 
1702261Sarnold 	nsp = &win->_y[wy][wx];
1712287Sarnold 	if (CE && !curwin) {
1722261Sarnold 		for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--)
1732261Sarnold 			if (ce <= win->_y[wy])
1742261Sarnold 				break;
1752261Sarnold 		nlsp = ce - win->_y[wy];
1762261Sarnold 	}
17719893Sbloom 
1782287Sarnold 	if (!curwin)
1792287Sarnold 		ce = CE;
1802287Sarnold 	else
1812287Sarnold 		ce = NULL;
18219893Sbloom 
1832261Sarnold 	while (wx <= lch) {
1842261Sarnold 		if (*nsp != *csp) {
18511736Sarnold 			domvcur(ly, lx, y, wx + win->_begx);
1862261Sarnold # ifdef DEBUG
1872261Sarnold 			fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx);
1882261Sarnold # endif
1892261Sarnold 			ly = y;
1902261Sarnold 			lx = wx + win->_begx;
1912261Sarnold 			while (*nsp != *csp && wx <= lch) {
1922287Sarnold 				if (ce != NULL && wx >= nlsp && *nsp == ' ') {
1932261Sarnold 					/*
1942261Sarnold 					 * check for clear to end-of-line
1952261Sarnold 					 */
1962261Sarnold 					ce = &curscr->_y[ly][COLS - 1];
1972261Sarnold 					while (*ce == ' ')
1982261Sarnold 						if (ce-- <= csp)
1992261Sarnold 							break;
2002261Sarnold 					clsp = ce - curscr->_y[ly] - win->_begx;
2012261Sarnold # ifdef DEBUG
2022261Sarnold 					fprintf(outf, "MAKECH: clsp = %d, nlsp = %d\n", clsp, nlsp);
2032261Sarnold # endif
2042261Sarnold 					if (clsp - nlsp >= strlen(CE)
2052261Sarnold 					    && clsp < win->_maxx) {
2062261Sarnold # ifdef DEBUG
2072261Sarnold 						fprintf(outf, "MAKECH: using CE\n");
2082261Sarnold # endif
2092261Sarnold 						_puts(CE);
2102261Sarnold 						lx = wx + win->_begx;
2112261Sarnold 						while (wx++ <= clsp)
2122261Sarnold 							*csp++ = ' ';
21319893Sbloom 						return OK;
2142261Sarnold 					}
2152261Sarnold 					ce = NULL;
2162261Sarnold 				}
2172261Sarnold 				/*
2182261Sarnold 				 * enter/exit standout mode as appropriate
2192261Sarnold 				 */
2202261Sarnold 				if (SO && (*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) {
2212261Sarnold 					if (*nsp & _STANDOUT) {
2222261Sarnold 						_puts(SO);
2232261Sarnold 						curscr->_flags |= _STANDOUT;
2242261Sarnold 					}
2252261Sarnold 					else {
2262261Sarnold 						_puts(SE);
2272261Sarnold 						curscr->_flags &= ~_STANDOUT;
2282261Sarnold 					}
2292261Sarnold 				}
2302261Sarnold 				wx++;
2312906Sarnold 				if (wx >= win->_maxx && wy == win->_maxy - 1)
2322287Sarnold 					if (win->_scroll) {
23311736Sarnold 					    if ((curscr->_flags&_STANDOUT) &&
23411736Sarnold 					        (win->_flags & _ENDLINE))
23511736Sarnold 						    if (!MS) {
23611736Sarnold 							_puts(SE);
23711736Sarnold 							curscr->_flags &= ~_STANDOUT;
23811736Sarnold 						    }
2392287Sarnold 					    if (!curwin)
24019893Sbloom 						_putchar((*csp = *nsp) & 0177);
2412287Sarnold 					    else
24219893Sbloom 						_putchar(*nsp & 0177);
2432287Sarnold 					    if (win->_flags&_FULLWIN && !curwin)
2442287Sarnold 						scroll(curscr);
2452287Sarnold 					    ly = win->_begy+win->_cury;
2462287Sarnold 					    lx = win->_begx+win->_curx;
2472287Sarnold 					    return OK;
2482287Sarnold 					}
2492287Sarnold 					else if (win->_flags&_SCROLLWIN) {
2502287Sarnold 					    lx = --wx;
2512287Sarnold 					    return ERR;
2522287Sarnold 					}
2532287Sarnold 				if (!curwin)
25419893Sbloom 					_putchar((*csp++ = *nsp) & 0177);
2552287Sarnold 				else
25619893Sbloom 					_putchar(*nsp & 0177);
25719893Sbloom # ifdef FULLDEBUG
25819893Sbloom 				fprintf(outf,
25919893Sbloom 					"MAKECH:putchar(%c)\n", *nsp & 0177);
26019893Sbloom # endif
2612261Sarnold 				if (UC && (*nsp & _STANDOUT)) {
26219893Sbloom 					_putchar('\b');
2632261Sarnold 					_puts(UC);
2642261Sarnold 				}
2652261Sarnold 				nsp++;
2662261Sarnold 			}
2672261Sarnold # ifdef DEBUG
2682261Sarnold 			fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
2692261Sarnold # endif
2702261Sarnold 			if (lx == wx + win->_begx)	/* if no change */
2712261Sarnold 				break;
2722261Sarnold 			lx = wx + win->_begx;
27322789Smckusick 			if (lx >= COLS && AM) {
27422789Smckusick 				lx = 0;
27522789Smckusick 				ly++;
27622789Smckusick 				/*
27722789Smckusick 				 * xn glitch: chomps a newline after auto-wrap.
27822789Smckusick 				 * we just feed it now and forget about it.
27922789Smckusick 				 */
28022789Smckusick 				if (XN) {
28122789Smckusick 					_putchar('\n');
28222789Smckusick 					_putchar('\r');
28322789Smckusick 				}
28422789Smckusick 			}
2852261Sarnold 		}
28622789Smckusick 		else if (wx <= lch)
28722789Smckusick 			while (*nsp == *csp && wx <= lch) {
2882287Sarnold 				nsp++;
2892287Sarnold 				if (!curwin)
2902287Sarnold 					csp++;
2912261Sarnold 				++wx;
2922261Sarnold 			}
2932261Sarnold 		else
2942261Sarnold 			break;
2952261Sarnold # ifdef DEBUG
2962261Sarnold 		fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
2972261Sarnold # endif
2982261Sarnold 	}
29911736Sarnold 	return OK;
30011736Sarnold }
30111736Sarnold 
30211736Sarnold /*
30311736Sarnold  * perform a mvcur, leaving standout mode if necessary
30411736Sarnold  */
30519893Sbloom STATIC
30611736Sarnold domvcur(oy, ox, ny, nx)
30711736Sarnold int	oy, ox, ny, nx; {
30811736Sarnold 
30911736Sarnold 	if (curscr->_flags & _STANDOUT && !MS) {
3102261Sarnold 		_puts(SE);
31111736Sarnold 		curscr->_flags &= ~_STANDOUT;
3122261Sarnold 	}
31311736Sarnold 	mvcur(oy, ox, ny, nx);
3142261Sarnold }
315