1 /* 2 * Copyright (c) 1981 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 /*static char sccsid[] = "from: @(#)refresh.c 5.5 (Berkeley) 3/3/91";*/ 36 static char rcsid[] = "$Id: refresh.c,v 1.3 1993/08/01 18:35:26 mycroft Exp $"; 37 #endif /* not lint */ 38 39 /* 40 * make the current screen look like "win" over the area coverd by 41 * win. 42 */ 43 44 # include "curses.ext" 45 46 # ifdef DEBUG 47 # define STATIC 48 # else 49 # define STATIC static 50 # endif 51 52 STATIC short ly, lx; 53 54 STATIC bool curwin; 55 56 WINDOW *_win = NULL; 57 58 STATIC int domvcur(), makech(); 59 60 wrefresh(win) 61 reg WINDOW *win; 62 { 63 reg short wy; 64 reg int retval; 65 reg WINDOW *orig; 66 67 /* 68 * make sure were in visual state 69 */ 70 if (_endwin) { 71 _puts(VS); 72 _puts(TI); 73 _endwin = FALSE; 74 } 75 76 /* 77 * initialize loop parameters 78 */ 79 80 ly = curscr->_cury; 81 lx = curscr->_curx; 82 wy = 0; 83 _win = win; 84 curwin = (win == curscr); 85 86 if (win->_clear || curscr->_clear || curwin) { 87 if ((win->_flags & _FULLWIN) || curscr->_clear) { 88 _puts(CL); 89 ly = 0; 90 lx = 0; 91 if (!curwin) { 92 curscr->_clear = FALSE; 93 curscr->_cury = 0; 94 curscr->_curx = 0; 95 werase(curscr); 96 } 97 touchwin(win); 98 } 99 win->_clear = FALSE; 100 } 101 if (!CA) { 102 if (win->_curx != 0) 103 _putchar('\n'); 104 if (!curwin) 105 werase(curscr); 106 } 107 # ifdef DEBUG 108 fprintf(outf, "REFRESH(%0.2o): curwin = %d\n", win, curwin); 109 fprintf(outf, "REFRESH:\n\tfirstch\tlastch\n"); 110 # endif 111 for (wy = 0; wy < win->_maxy; wy++) { 112 # ifdef DEBUG 113 fprintf(outf, "%d\t%d\t%d\n", wy, win->_firstch[wy], 114 win->_lastch[wy]); 115 # endif 116 if (win->_firstch[wy] != _NOCHANGE) 117 if (makech(win, wy) == ERR) 118 return ERR; 119 else { 120 if (win->_firstch[wy] >= win->_ch_off) 121 win->_firstch[wy] = win->_maxx + 122 win->_ch_off; 123 if (win->_lastch[wy] < win->_maxx + 124 win->_ch_off) 125 win->_lastch[wy] = win->_ch_off; 126 if (win->_lastch[wy] < win->_firstch[wy]) 127 win->_firstch[wy] = _NOCHANGE; 128 } 129 # ifdef DEBUG 130 fprintf(outf, "\t%d\t%d\n", win->_firstch[wy], 131 win->_lastch[wy]); 132 # endif 133 } 134 135 if (win == curscr) 136 domvcur(ly, lx, win->_cury, win->_curx); 137 else { 138 if (win->_leave) { 139 curscr->_cury = ly; 140 curscr->_curx = lx; 141 ly -= win->_begy; 142 lx -= win->_begx; 143 if (ly >= 0 && ly < win->_maxy && lx >= 0 && 144 lx < win->_maxx) { 145 win->_cury = ly; 146 win->_curx = lx; 147 } 148 else 149 win->_cury = win->_curx = 0; 150 } 151 else { 152 domvcur(ly, lx, win->_cury + win->_begy, 153 win->_curx + win->_begx); 154 curscr->_cury = win->_cury + win->_begy; 155 curscr->_curx = win->_curx + win->_begx; 156 } 157 } 158 retval = OK; 159 ret: 160 _win = NULL; 161 fflush(stdout); 162 return retval; 163 } 164 165 /* 166 * make a change on the screen 167 */ 168 STATIC 169 makech(win, wy) 170 reg WINDOW *win; 171 short wy; 172 { 173 reg chtype *nsp, *csp, *ce; 174 reg short wx, lch, y; 175 reg int nlsp, clsp; /* last space in lines */ 176 char *ce_tcap; 177 static chtype blank[] = {' ','\0'}; 178 179 wx = win->_firstch[wy] - win->_ch_off; 180 if (wx >= win->_maxx) 181 return OK; 182 else if (wx < 0) 183 wx = 0; 184 lch = win->_lastch[wy] - win->_ch_off; 185 if (lch < 0) 186 return OK; 187 else if (lch >= win->_maxx) 188 lch = win->_maxx - 1;; 189 y = wy + win->_begy; 190 191 if (curwin) 192 csp = blank; 193 else 194 csp = &curscr->_y[wy + win->_begy][wx + win->_begx]; 195 196 nsp = &win->_y[wy][wx]; 197 if (CE && !curwin) { 198 for (ce = &win->_y[wy][win->_maxx - 1]; *ce == ' '; ce--) 199 if (ce <= win->_y[wy]) 200 break; 201 nlsp = ce - win->_y[wy]; 202 } 203 204 if (!curwin) 205 ce_tcap = CE; 206 else 207 ce_tcap = NULL; 208 209 while (wx <= lch) { 210 if (*nsp != *csp) { 211 domvcur(ly, lx, y, wx + win->_begx); 212 # ifdef DEBUG 213 fprintf(outf, "MAKECH: 1: wx = %d, lx = %d\n", wx, lx); 214 # endif 215 ly = y; 216 lx = wx + win->_begx; 217 while (*nsp != *csp && wx <= lch) { 218 if (ce_tcap != NULL && wx >= nlsp && *nsp == ' ') { 219 /* 220 * check for clear to end-of-line 221 */ 222 ce = &curscr->_y[ly][COLS - 1]; 223 while (*ce == ' ') 224 if (ce-- <= csp) 225 break; 226 clsp = ce - curscr->_y[ly] - win->_begx; 227 # ifdef DEBUG 228 fprintf(outf, "MAKECH: clsp = %d, nlsp = %d\n", clsp, nlsp); 229 # endif 230 if (clsp - nlsp >= strlen(CE) 231 && clsp < win->_maxx) { 232 # ifdef DEBUG 233 fprintf(outf, "MAKECH: using CE\n"); 234 # endif 235 _puts(CE); 236 lx = wx + win->_begx; 237 while (wx++ <= clsp) 238 *csp++ = ' '; 239 return OK; 240 } 241 ce_tcap = NULL; 242 } 243 /* 244 * enter/exit standout mode as appropriate 245 */ 246 if (SO && (*nsp&_STANDOUT) != (curscr->_flags&_STANDOUT)) { 247 if (*nsp & _STANDOUT) { 248 _puts(SO); 249 curscr->_flags |= _STANDOUT; 250 } 251 else { 252 _puts(SE); 253 curscr->_flags &= ~_STANDOUT; 254 } 255 } 256 wx++; 257 if (wx >= win->_maxx && wy == win->_maxy - 1) 258 if (win->_scroll) { 259 if ((curscr->_flags&_STANDOUT) && 260 (win->_flags & _ENDLINE)) 261 if (!MS) { 262 _puts(SE); 263 curscr->_flags &= ~_STANDOUT; 264 } 265 if (!curwin) 266 _putchar((*csp = *nsp)); 267 else 268 _putchar(*nsp); 269 if (win->_flags&_FULLWIN && !curwin) 270 scroll(curscr); 271 ly = win->_begy+win->_cury; 272 lx = win->_begx+win->_curx; 273 return OK; 274 } 275 else if (win->_flags&_SCROLLWIN) { 276 lx = --wx; 277 return ERR; 278 } 279 if (!curwin) 280 _putchar((*csp++ = *nsp)); 281 else 282 _putchar(*nsp); 283 # ifdef FULLDEBUG 284 fprintf(outf, 285 "MAKECH:putchar(%c)\n", *nsp); 286 # endif 287 if (UC && (*nsp & _STANDOUT)) { 288 _putchar('\b'); 289 _puts(UC); 290 } 291 nsp++; 292 } 293 # ifdef DEBUG 294 fprintf(outf, "MAKECH: 2: wx = %d, lx = %d\n", wx, lx); 295 # endif 296 if (lx == wx + win->_begx) /* if no change */ 297 break; 298 lx = wx + win->_begx; 299 if (lx >= COLS && AM) { 300 lx = 0; 301 ly++; 302 /* 303 * xn glitch: chomps a newline after auto-wrap. 304 * we just feed it now and forget about it. 305 */ 306 if (XN) { 307 _putchar('\n'); 308 _putchar('\r'); 309 } 310 } 311 } 312 else if (wx <= lch) 313 while (*nsp == *csp && wx <= lch) { 314 nsp++; 315 if (!curwin) 316 csp++; 317 ++wx; 318 } 319 else 320 break; 321 # ifdef DEBUG 322 fprintf(outf, "MAKECH: 3: wx = %d, lx = %d\n", wx, lx); 323 # endif 324 } 325 return OK; 326 } 327 328 /* 329 * perform a mvcur, leaving standout mode if necessary 330 */ 331 STATIC 332 domvcur(oy, ox, ny, nx) 333 int oy, ox, ny, nx; { 334 335 if (curscr->_flags & _STANDOUT && !MS) { 336 _puts(SE); 337 curscr->_flags &= ~_STANDOUT; 338 } 339 mvcur(oy, ox, ny, nx); 340 } 341