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