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