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