Home | History | Annotate | Download | only in libcurses
      1 /*
      2  * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
      3  * Use is subject to license terms.
      4  */
      5 
      6 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
      7 /*	  All Rights Reserved  	*/
      8 
      9 /*
     10  * Copyright (c) 1980 Regents of the University of California.
     11  * All rights reserved.  The Berkeley software License Agreement
     12  * specifies the terms and conditions for redistribution.
     13  */
     14 
     15 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     16 
     17 /*LINTLIBRARY*/
     18 
     19 #ifndef lint
     20 static char
     21 sccsid[] = "@(#)refresh.c 1.8 89/08/24 SMI"; /* from UCB 5.1 85/06/07 */
     22 #endif /* not lint */
     23 
     24 /*
     25  * make the current screen look like "win" over the area coverd by
     26  * win.
     27  */
     28 
     29 #include	"curses.ext"
     30 #include	<term.h>
     31 #include	<string.h>
     32 
     33 #ifdef DEBUG
     34 #define	DEBUGSTATIC
     35 #else
     36 #define	DEBUGSTATIC	static
     37 #endif
     38 
     39 DEBUGSTATIC short	ly, lx;
     40 DEBUGSTATIC bool	curwin;
     41 WINDOW	*_win = NULL;
     42 
     43 /* forward declarations */
     44 DEBUGSTATIC void domvcur(int, int, int, int);
     45 DEBUGSTATIC int makech(WINDOW *, short);
     46 
     47 int
     48 wrefresh(WINDOW *win)
     49 {
     50 	short	wy;
     51 	int	retval;
     52 
     53 	/*
     54 	 * make sure were in visual state
     55 	 */
     56 	if (_endwin) {
     57 		(void) _puts(VS);
     58 		(void) _puts(TI);
     59 		_endwin = FALSE;
     60 	}
     61 
     62 	/*
     63 	 * initialize loop parameters
     64 	 */
     65 
     66 	ly = curscr->_cury;
     67 	lx = curscr->_curx;
     68 	_win = win;
     69 	curwin = (win == curscr);
     70 
     71 	if (win->_clear || curscr->_clear || curwin) {
     72 		if ((win->_flags & _FULLWIN) || curscr->_clear) {
     73 			(void) _puts(CL);
     74 			ly = 0;
     75 			lx = 0;
     76 			if (!curwin) {
     77 				curscr->_clear = FALSE;
     78 				curscr->_cury = 0;
     79 				curscr->_curx = 0;
     80 				(void) werase(curscr);
     81 			}
     82 			(void) touchwin(win);
     83 		}
     84 		win->_clear = FALSE;
     85 	}
     86 	if (!CA) {
     87 		if (win->_curx != 0)
     88 			(void) _putchar('\n');
     89 		if (!curwin)
     90 			(void) werase(curscr);
     91 	}
     92 #ifdef DEBUG
     93 	fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin);
     94 	fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n");
     95 #endif
     96 	for (wy = 0; wy < win->_maxy; wy++) {
     97 #ifdef DEBUG
     98 		fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy],
     99 		    win->_lastch[wy]);
    100 #endif
    101 		if (win->_firstch[wy] != _NOCHANGE)
    102 			if (makech(win, wy) == ERR)
    103 				return (ERR);
    104 			else {
    105 				if (win->_firstch[wy] >= win->_ch_off)
    106 					win->_firstch[wy] = win->_maxx +
    107 							    win->_ch_off;
    108 				if (win->_lastch[wy] < win->_maxx +
    109 				    win->_ch_off)
    110 					win->_lastch[wy] = win->_ch_off;
    111 				if (win->_lastch[wy] < win->_firstch[wy])
    112 					win->_firstch[wy] = _NOCHANGE;
    113 			}
    114 #ifdef DEBUG
    115 		fprintf(outf, "\t%d\t%d\n", win->_firstch[wy],
    116 		    win->_lastch[wy]);
    117 #endif
    118 	}
    119 
    120 	if (win == curscr)
    121 		domvcur(ly, lx, win->_cury, win->_curx);
    122 	else {
    123 		if (win->_leave) {
    124 			curscr->_cury = ly;
    125 			curscr->_curx = lx;
    126 			ly -= win->_begy;
    127 			lx -= win->_begx;
    128 			if (ly >= 0 && ly < win->_maxy && lx >= 0 &&
    129 			    lx < win->_maxx) {
    130 				win->_cury = ly;
    131 				win->_curx = lx;
    132 			}
    133 			else
    134 				win->_cury = win->_curx = 0;
    135 		} else {
    136 			domvcur(ly, lx, win->_cury + win->_begy,
    137 				win->_curx + win->_begx);
    138 			curscr->_cury = win->_cury + win->_begy;
    139 			curscr->_curx = win->_curx + win->_begx;
    140 		}
    141 	}
    142 	retval = OK;
    143 
    144 	_win = NULL;
    145 	(void) fflush(stdout);
    146 	return (retval);
    147 }
    148 
    149 /*
    150  * make a change on the screen
    151  */
    152 
    153 DEBUGSTATIC int
    154 makech(WINDOW *win, short wy)
    155 {
    156 	char	*nsp, *csp, *ce;
    157 	short	wx, lch, y;
    158 	intptr_t	nlsp, clsp;	/* last space in lines		*/
    159 
    160 	wx = win->_firstch[wy] - win->_ch_off;
    161 	if (wx >= win->_maxx)
    162 		return (OK);
    163 	else if (wx < 0)
    164 		wx = 0;
    165 	lch = win->_lastch[wy] - win->_ch_off;
    166 	if (lch < 0)
    167 		return (OK);
    168 	else if (lch >= win->_maxx)
    169 		lch = win->_maxx - 1;
    170 	y = wy + win->_begy;
    171 
    172 	if (curwin)
    173 		csp = " ";
    174 	else
    175 		csp = &curscr->_y[wy + win->_begy][wx + win->_begx];
    176 
    177 	nsp = &win->_y[wy][wx];
    178 	if (CE && !curwin) {
    179 		for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--)
    180 			if (ce <= win->_y[wy])
    181 				break;
    182 		nlsp = ce - win->_y[wy];
    183 	}
    184 
    185 	if (!curwin)
    186 		ce = CE;
    187 	else
    188 		ce = NULL;
    189 
    190 	while (wx <= lch) {
    191 		if (*nsp != *csp) {
    192 			domvcur(ly, lx, y, wx + win->_begx);
    193 #ifdef DEBUG
    194 			fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx);
    195 #endif
    196 			ly = y;
    197 			lx = wx + win->_begx;
    198 			while (wx <= lch && *nsp != *csp) {
    199 				if (ce != NULL && wx >= nlsp && *nsp == ' ') {
    200 					/*
    201 					 * check for clear to end-of-line
    202 					 */
    203 					ce = &curscr->_y[ly][COLS - 1];
    204 					while (*ce == ' ')
    205 						if (ce-- <= csp)
    206 							break;
    207 					clsp = ce - curscr->_y[ly] - win->_begx;
    208 #ifdef DEBUG
    209 					fprintf(outf, "MAKECH: clsp = %d,"
    210 					    " nlsp = %d\n", clsp, nlsp);
    211 #endif
    212 					if (clsp - nlsp >= strlen(CE) &&
    213 					    clsp < win->_maxx) {
    214 #ifdef DEBUG
    215 						fprintf(outf, "MAKECH: using"
    216 						    " CE\n");
    217 #endif
    218 						(void) _puts(CE);
    219 						lx = wx + win->_begx;
    220 						while (wx++ <= clsp)
    221 							*csp++ = ' ';
    222 						return (OK);
    223 					}
    224 					ce = NULL;
    225 				}
    226 				/*
    227 				 * enter/exit standout mode as appropriate
    228 				 */
    229 				if (SO && (*nsp&_STANDOUT) !=
    230 				    (curscr->_flags&_STANDOUT)) {
    231 					if (*nsp & _STANDOUT) {
    232 						(void) _puts(SO);
    233 						curscr->_flags |= _STANDOUT;
    234 					} else {
    235 						(void) _puts(SE);
    236 						curscr->_flags &= ~_STANDOUT;
    237 					}
    238 				}
    239 				wx++;
    240 				if (wx >= win->_maxx && wy == win->_maxy - 1)
    241 					if (win->_scroll) {
    242 					    if ((curscr->_flags&_STANDOUT) &&
    243 						(win->_flags & _ENDLINE))
    244 						    if (!MS) {
    245 							(void) _puts(SE);
    246 							curscr->_flags &=
    247 							    ~_STANDOUT;
    248 						    }
    249 					    if (!curwin)
    250 						(void) _putchar((*csp = *nsp) &
    251 						    0177);
    252 					    else
    253 						(void) _putchar(*nsp & 0177);
    254 					    if (win->_flags&_FULLWIN && !curwin)
    255 						(void) scroll(curscr);
    256 					    if (!curwin) {
    257 						    ly = wy + win->_begy;
    258 						    lx = wx + win->_begx;
    259 					    } else {
    260 						    ly = win->_begy+win->_cury;
    261 						    lx = win->_begx+win->_curx;
    262 					    }
    263 					    return (OK);
    264 					} else if (win->_flags&_SCROLLWIN) {
    265 					    wx = wx - 1;
    266 					    lx = wx;
    267 					    return (ERR);
    268 					}
    269 				if (!curwin)
    270 					(void) _putchar((*csp++ = *nsp) & 0177);
    271 				else
    272 					(void) _putchar(*nsp & 0177);
    273 #ifdef FULLDEBUG
    274 				fprintf(outf,
    275 					"MAKECH:putchar(%c)\n", *nsp & 0177);
    276 #endif
    277 				if (UC && (*nsp & _STANDOUT)) {
    278 					(void) _putchar('\b');
    279 					(void) _puts(UC);
    280 				}
    281 				nsp++;
    282 			}
    283 #ifdef DEBUG
    284 			fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx);
    285 #endif
    286 			if (lx == wx + win->_begx)	/* if no change */
    287 				break;
    288 			lx = wx + win->_begx;
    289 			if (lx >= COLS && AM) {
    290 				lx = 0;
    291 				ly++;
    292 				/*
    293 				 * xn glitch: chomps a newline after auto-wrap.
    294 				 * we just feed it now and forget about it.
    295 				 */
    296 				if (XN) {
    297 					(void) _putchar('\n');
    298 					(void) _putchar('\r');
    299 				}
    300 			}
    301 		} else if (wx <= lch)
    302 			while (wx <= lch && *nsp == *csp) {
    303 				nsp++;
    304 				if (!curwin)
    305 					csp++;
    306 				++wx;
    307 			}
    308 		else
    309 			break;
    310 #ifdef DEBUG
    311 		fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx);
    312 #endif
    313 	}
    314 	return (OK);
    315 }
    316 
    317 /*
    318  * perform a mvcur, leaving standout mode if necessary
    319  */
    320 
    321 DEBUGSTATIC void
    322 domvcur(int oy, int ox, int ny, int nx)
    323 {
    324 	if (curscr->_flags & _STANDOUT && !MS) {
    325 		(void) _puts(SE);
    326 		curscr->_flags &= ~_STANDOUT;
    327 	}
    328 	(void) mvcur(oy, ox, ny, nx);
    329 }
    330