12261Sarnold /* 234677Sbostic * Copyright (c) 1981 Regents of the University of California. 334677Sbostic * All rights reserved. 434677Sbostic * 542657Sbostic * %sccs.include.redist.c% 622791Smckusick */ 722791Smckusick 822791Smckusick #ifndef lint 9*56238Selan static char sccsid[] = "@(#)refresh.c 5.9 (Berkeley) 09/14/92"; 1034677Sbostic #endif /* not lint */ 1122791Smckusick 1255976Sbostic #include <curses.h> 1355986Sbostic #include <string.h> 142261Sarnold 1555976Sbostic static int curwin; 1655976Sbostic static short ly, lx; 172261Sarnold 1855976Sbostic WINDOW *_win; 192261Sarnold 2055976Sbostic static void domvcur __P((int, int, int, int)); 2155976Sbostic static int makech __P((WINDOW *, int)); 222287Sarnold 2355976Sbostic /* 2455976Sbostic * wrefresh -- 2555976Sbostic * Make the current screen look like "win" over the area coverd by 2655976Sbostic * win. 2755976Sbostic */ 2855976Sbostic int 292261Sarnold wrefresh(win) 3055976Sbostic register WINDOW *win; 312261Sarnold { 3255976Sbostic register int retval; 3355976Sbostic register short wy; 342261Sarnold 3555976Sbostic /* Make sure were in visual state. */ 3655976Sbostic if (__endwin) { 3755976Sbostic tputs(VS, 0, __cputchar); 3855976Sbostic tputs(TI, 0, __cputchar); 3955976Sbostic __endwin = 0; 402261Sarnold } 412287Sarnold 4255976Sbostic /* Initialize loop parameters. */ 432287Sarnold 44*56238Selan ly = curscr->cury; 45*56238Selan lx = curscr->curx; 462287Sarnold wy = 0; 472287Sarnold _win = win; 482287Sarnold curwin = (win == curscr); 492287Sarnold 50*56238Selan if (win->flags & __CLEAROK || curscr->flags & __CLEAROK || curwin) { 51*56238Selan if ((win->flags & __FULLWIN) || curscr->flags & __CLEAROK) { 5255976Sbostic tputs(CL, 0, __cputchar); 5312358Sarnold ly = 0; 5412358Sarnold lx = 0; 5512358Sarnold if (!curwin) { 56*56238Selan curscr->flags &= ~__CLEAROK; 57*56238Selan curscr->cury = 0; 58*56238Selan curscr->curx = 0; 592287Sarnold werase(curscr); 6012358Sarnold } 612261Sarnold touchwin(win); 622261Sarnold } 63*56238Selan win->flags &= ~__CLEAROK; 642261Sarnold } 652261Sarnold if (!CA) { 66*56238Selan if (win->curx != 0) 6755976Sbostic putchar('\n'); 682287Sarnold if (!curwin) 692287Sarnold werase(curscr); 702261Sarnold } 7155976Sbostic #ifdef DEBUG 7255976Sbostic __TRACE("wrefresh: (%0.2o): curwin = %d\n", win, curwin); 7355976Sbostic __TRACE("wrefresh: \tfirstch\tlastch\n"); 7455976Sbostic #endif 75*56238Selan for (wy = 0; wy < win->maxy; wy++) { 7655976Sbostic #ifdef DEBUG 7755976Sbostic __TRACE("%d\t%d\t%d\n", 78*56238Selan wy, win->lines[wy]->firstch, win->lines[wy]->lastch); 7955976Sbostic #endif 80*56238Selan if (win->lines[wy]->flags & __ISDIRTY) 812261Sarnold if (makech(win, wy) == ERR) 8255976Sbostic return (ERR); 8319893Sbloom else { 84*56238Selan if (win->lines[wy]->firstch >= win->ch_off) 85*56238Selan win->lines[wy]->firstch = win->maxx + 86*56238Selan win->ch_off; 87*56238Selan if (win->lines[wy]->lastch < win->maxx + 88*56238Selan win->ch_off) 89*56238Selan win->lines[wy]->lastch = win->ch_off; 90*56238Selan if (win->lines[wy]->lastch < 91*56238Selan win->lines[wy]->firstch) 92*56238Selan win->lines[wy]->flags &= ~__ISDIRTY; 9319893Sbloom } 9455976Sbostic #ifdef DEBUG 95*56238Selan __TRACE("\t%d\t%d\n", win->lines[wy]->firstch, 96*56238Selan win->lines[wy]->lastch); 9755976Sbostic #endif 982261Sarnold } 99*56238Selan 100*56238Selan __TRACE("refresh: ly=%d, lx=%d\n", ly, lx); 10112358Sarnold if (win == curscr) 102*56238Selan domvcur(ly, lx, win->cury, win->curx); 10319893Sbloom else { 104*56238Selan if (win->flags & __LEAVEOK) { 105*56238Selan curscr->cury = ly; 106*56238Selan curscr->curx = lx; 107*56238Selan ly -= win->begy; 108*56238Selan lx -= win->begx; 109*56238Selan if (ly >= 0 && ly < win->maxy && lx >= 0 && 110*56238Selan lx < win->maxx) { 111*56238Selan win->cury = ly; 112*56238Selan win->curx = lx; 11355976Sbostic } else 114*56238Selan win->cury = win->curx = 0; 11555976Sbostic } else { 116*56238Selan domvcur(ly, lx, win->cury + win->begy, 117*56238Selan win->curx + win->begx); 118*56238Selan curscr->cury = win->cury + win->begy; 119*56238Selan curscr->curx = win->curx + win->begx; 12019893Sbloom } 1212261Sarnold } 1222287Sarnold retval = OK; 12355986Sbostic 1242261Sarnold _win = NULL; 12555976Sbostic (void)fflush(stdout); 12655976Sbostic return (retval); 1272261Sarnold } 1282261Sarnold 1292261Sarnold /* 13055976Sbostic * makech -- 13155976Sbostic * Make a change on the screen. 1322261Sarnold */ 13355976Sbostic static int 1342261Sarnold makech(win, wy) 13555976Sbostic register WINDOW *win; 13655976Sbostic int wy; 1372261Sarnold { 13855976Sbostic register int nlsp, clsp; /* Last space in lines. */ 13955976Sbostic register short wx, lch, y; 14055976Sbostic register char *nsp, *csp, *ce; 1412261Sarnold 142*56238Selan if (!(win->lines[wy]->flags & __ISDIRTY)) 14355976Sbostic return (OK); 144*56238Selan wx = win->lines[wy]->firstch - win->ch_off; 145*56238Selan if (wx >= win->maxx) 146*56238Selan return (OK); 14719893Sbloom else if (wx < 0) 14819893Sbloom wx = 0; 149*56238Selan lch = win->lines[wy]->lastch - win->ch_off; 15019893Sbloom if (lch < 0) 15155976Sbostic return (OK); 152*56238Selan else if (lch >= win->maxx) 153*56238Selan lch = win->maxx - 1; 154*56238Selan y = wy + win->begy; 15519893Sbloom 1562287Sarnold if (curwin) 1572287Sarnold csp = " "; 1582287Sarnold else 159*56238Selan csp = &curscr->lines[wy + win->begy]->line[wx + win->begx]; 16019893Sbloom 161*56238Selan nsp = &win->lines[wy]->line[wx]; 1622287Sarnold if (CE && !curwin) { 163*56238Selan for (ce = &win->lines[wy]->line[win->maxx - 1]; 164*56238Selan *ce == ' '; ce--) 165*56238Selan if (ce <= win->lines[wy]->line) 1662261Sarnold break; 167*56238Selan nlsp = ce - win->lines[wy]->line; 1682261Sarnold } 1692287Sarnold if (!curwin) 1702287Sarnold ce = CE; 1712287Sarnold else 1722287Sarnold ce = NULL; 17319893Sbloom 1742261Sarnold while (wx <= lch) { 17555986Sbostic if (*nsp == *csp) { 17655986Sbostic if (wx <= lch) { 17755986Sbostic while (*nsp == *csp && wx <= lch) { 17855986Sbostic nsp++; 17955986Sbostic if (!curwin) 18055986Sbostic csp++; 18155986Sbostic ++wx; 18255986Sbostic } 18355986Sbostic continue; 18455986Sbostic } 18555986Sbostic break; 18655986Sbostic } 187*56238Selan domvcur(ly, lx, y, wx + win->begx); 18855976Sbostic #ifdef DEBUG 18956114Selan __TRACE("makech: 1: wx = %d, lx = %d, newy = %d, newx = %d\n", 190*56238Selan wx, lx, y, wx + win->begx); 19155976Sbostic #endif 19255986Sbostic ly = y; 193*56238Selan lx = wx + win->begx; 19455986Sbostic while (*nsp != *csp && wx <= lch) { 19555986Sbostic if (ce != NULL && wx >= nlsp && *nsp == ' ') { 19655986Sbostic /* Check for clear to end-of-line. */ 197*56238Selan ce = &curscr->lines[ly]->line[COLS - 1]; 19855986Sbostic while (*ce == ' ') 19955986Sbostic if (ce-- <= csp) 20055986Sbostic break; 201*56238Selan clsp = ce - curscr->lines[ly]->line - 202*56238Selan win->begx; 20355976Sbostic #ifdef DEBUG 20455986Sbostic __TRACE("makech: clsp = %d, nlsp = %d\n", clsp, nlsp); 20555976Sbostic #endif 20655986Sbostic if (clsp - nlsp >= strlen(CE) && 207*56238Selan clsp < win->maxx) { 20855976Sbostic #ifdef DEBUG 20955986Sbostic __TRACE("makech: using CE\n"); 21055976Sbostic #endif 21155986Sbostic tputs(CE, 0, __cputchar); 212*56238Selan lx = wx + win->begx; 21355986Sbostic while (wx++ <= clsp) 21455986Sbostic *csp++ = ' '; 21555986Sbostic return (OK); 2162261Sarnold } 21755986Sbostic ce = NULL; 21855986Sbostic } 21955986Sbostic 22055986Sbostic /* Enter/exit standout mode as appropriate. */ 221*56238Selan if (SO && (*nsp & __STANDOUT) != 222*56238Selan (curscr->flags & __STANDOUT)) { 223*56238Selan if (*nsp & __STANDOUT) { 22455986Sbostic tputs(SO, 0, __cputchar); 225*56238Selan curscr->flags |= __WSTANDOUT; 22655986Sbostic } else { 22755986Sbostic tputs(SE, 0, __cputchar); 228*56238Selan curscr->flags &= ~__WSTANDOUT; 2292261Sarnold } 23055986Sbostic } 23155986Sbostic 23255986Sbostic wx++; 233*56238Selan if (wx >= win->maxx && wy == win->maxy - 1) 234*56238Selan if (win->flags & __SCROLLOK) { 235*56238Selan if (curscr->flags & __WSTANDOUT 236*56238Selan && win->flags & __ENDLINE) 23755986Sbostic if (!MS) { 23855986Sbostic tputs(SE, 0, 23955986Sbostic __cputchar); 240*56238Selan curscr->flags &= 241*56238Selan ~__WSTANDOUT; 24255976Sbostic } 24355986Sbostic if (!curwin) 24455986Sbostic putchar((*csp = *nsp) & 0177); 24555986Sbostic else 24655986Sbostic putchar(*nsp & 0177); 247*56238Selan if (win->flags & __FULLWIN && !curwin) 24855986Sbostic scroll(curscr); 249*56238Selan ly = win->begy + wy; 250*56238Selan lx = win->begx + wx; 25155986Sbostic return (OK); 25255986Sbostic } else 253*56238Selan if (win->flags & __SCROLLWIN) { 25455986Sbostic lx = --wx; 25555986Sbostic return (ERR); 25655986Sbostic } 25755986Sbostic if (!curwin) 25855986Sbostic putchar((*csp++ = *nsp) & 0177); 25955986Sbostic else 26055986Sbostic putchar(*nsp & 0177); 26155976Sbostic #ifdef DEBUG 26255986Sbostic __TRACE("makech: putchar(%c)\n", *nsp & 0177); 26355976Sbostic #endif 264*56238Selan if (UC && (*nsp & __STANDOUT)) { 26555986Sbostic putchar('\b'); 26655986Sbostic tputs(UC, 0, __cputchar); 2672261Sarnold } 26855986Sbostic nsp++; 26955986Sbostic } 27055976Sbostic #ifdef DEBUG 27155986Sbostic __TRACE("makech: 2: wx = %d, lx = %d\n", wx, lx); 27255976Sbostic #endif 273*56238Selan if (lx == wx + win->begx) /* If no change. */ 27455986Sbostic break; 275*56238Selan lx = wx + win->begx; 27655986Sbostic if (lx >= COLS && AM) { 27755986Sbostic lx = 0; 27855986Sbostic ly++; 27955986Sbostic /* 28055986Sbostic * xn glitch: chomps a newline after auto-wrap. 28155986Sbostic * we just feed it now and forget about it. 28255986Sbostic */ 28355986Sbostic if (XN) { 28455986Sbostic putchar('\n'); 28555986Sbostic putchar('\r'); 28622789Smckusick } 28755986Sbostic } 28855976Sbostic #ifdef DEBUG 28955976Sbostic __TRACE("makech: 3: wx = %d, lx = %d\n", wx, lx); 29055976Sbostic #endif 2912261Sarnold } 29255976Sbostic return (OK); 29311736Sarnold } 29411736Sarnold 29511736Sarnold /* 29655976Sbostic * domvcur -- 29755976Sbostic * Do a mvcur, leaving standout mode if necessary. 29811736Sarnold */ 29955976Sbostic static void 30011736Sarnold domvcur(oy, ox, ny, nx) 30155976Sbostic int oy, ox, ny, nx; 30255976Sbostic { 303*56238Selan if (curscr->flags & __WSTANDOUT && !MS) { 30455976Sbostic tputs(SE, 0, __cputchar); 305*56238Selan curscr->flags &= ~__WSTANDOUT; 3062261Sarnold } 30711736Sarnold mvcur(oy, ox, ny, nx); 3082261Sarnold } 309