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