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