📄 refresh.c
字号:
lx = win->begx + win->maxx - 1; return (OK); } if (wx < win->maxx || wy < win->maxy - 1 || !(win->flags & __SCROLLWIN)) { if (!curwin) { csp->attr = nsp->attr; putchar(csp->ch = nsp->ch); csp++; } else putchar(nsp->ch); }#ifdef DEBUG __CTRACE("makech: putchar(%c)\n", nsp->ch & 0177);#endif if (UC && (nsp->attr & __STANDOUT)) { putchar('\b'); tputs(UC, 0, __cputchar); } nsp++;#ifdef DEBUG __CTRACE("makech: 2: wx = %d, lx = %d\n", wx, lx);#endif } if (lx == wx + win->begx) /* If no change. */ break; lx = wx + win->begx; if (lx >= COLS && AM) lx = COLS - 1; else if (wx >= win->maxx) { domvcur(ly, lx, ly, win->maxx + win->begx - 1); lx = win->maxx + win->begx - 1; }#ifdef DEBUG __CTRACE("makech: 3: wx = %d, lx = %d\n", wx, lx);#endif } return (OK);}/* * domvcur -- * Do a mvcur, leaving standout mode if necessary. */static voiddomvcur(oy, ox, ny, nx) int oy, ox, ny, nx;{ if (curscr->flags & __WSTANDOUT && !MS) { tputs(SE, 0, __cputchar); curscr->flags &= ~__WSTANDOUT; } __mvcur(oy, ox, ny, nx, 1);}/* * Quickch() attempts to detect a pattern in the change of the window * in order to optimize the change, e.g., scroll n lines as opposed to * repainting the screen line by line. */static voidquickch(win) WINDOW *win;{#define THRESH (int) win->maxy / 4 register __LINE *clp, *tmp1, *tmp2; register int bsize, curs, curw, starts, startw, i, j; int n, target, cur_period, bot, top, sc_region; __LDATA buf[1024]; u_int blank_hash; /* * Find how many lines from the top of the screen are unchanged. */ for (top = 0; top < win->maxy; top++) if (win->lines[top]->flags & __FORCEPAINT || win->lines[top]->hash != curscr->lines[top]->hash || memcmp(win->lines[top]->line, curscr->lines[top]->line, win->maxx * __LDATASIZE) != 0) break; else win->lines[top]->flags &= ~__ISDIRTY; /* * Find how many lines from bottom of screen are unchanged. */ for (bot = win->maxy - 1; bot >= 0; bot--) if (win->lines[bot]->flags & __FORCEPAINT || win->lines[bot]->hash != curscr->lines[bot]->hash || memcmp(win->lines[bot]->line, curscr->lines[bot]->line, win->maxx * __LDATASIZE) != 0) break; else win->lines[bot]->flags &= ~__ISDIRTY;#ifdef NO_JERKINESS /* * If we have a bottom unchanged region return. Scrolling the * bottom region up and then back down causes a screen jitter. * This will increase the number of characters sent to the screen * but it looks better. */ if (bot < win->maxy - 1) return;#endif /* NO_JERKINESS */ /* * Search for the largest block of text not changed. * Invariants of the loop: * - Startw is the index of the beginning of the examined block in win. * - Starts is the index of the beginning of the examined block in * curscr. * - Curs is the index of one past the end of the exmined block in win. * - Curw is the index of one past the end of the exmined block in * curscr. * - bsize is the current size of the examined block. */ for (bsize = bot - top; bsize >= THRESH; bsize--) { for (startw = top; startw <= bot - bsize; startw++) for (starts = top; starts <= bot - bsize; starts++) { for (curw = startw, curs = starts; curs < starts + bsize; curw++, curs++) if (win->lines[curw]->flags & __FORCEPAINT || (win->lines[curw]->hash != curscr->lines[curs]->hash || memcmp(win->lines[curw]->line, curscr->lines[curs]->line, win->maxx * __LDATASIZE) != 0)) break; if (curs == starts + bsize) goto done; } } done: /* Did not find anything */ if (bsize < THRESH) return;#ifdef DEBUG __CTRACE("quickch:bsize=%d,starts=%d,startw=%d,curw=%d,curs=%d,top=%d,bot=%d\n", bsize, starts, startw, curw, curs, top, bot);#endif /* * Make sure that there is no overlap between the bottom and top * regions and the middle scrolled block. */ if (bot < curs) bot = curs - 1; if (top > starts) top = starts; n = startw - starts;#ifdef DEBUG __CTRACE("#####################################\n"); for (i = 0; i < curscr->maxy; i++) { __CTRACE("C: %d:", i); __CTRACE(" 0x%x \n", curscr->lines[i]->hash); for (j = 0; j < curscr->maxx; j++) __CTRACE("%c", curscr->lines[i]->line[j].ch); __CTRACE("\n"); for (j = 0; j < curscr->maxx; j++) __CTRACE("%x", curscr->lines[i]->line[j].attr); __CTRACE("\n"); __CTRACE("W: %d:", i); __CTRACE(" 0x%x \n", win->lines[i]->hash); __CTRACE(" 0x%x ", win->lines[i]->flags); for (j = 0; j < win->maxx; j++) __CTRACE("%c", win->lines[i]->line[j].ch); __CTRACE("\n"); for (j = 0; j < win->maxx; j++) __CTRACE("%x", win->lines[i]->line[j].attr); __CTRACE("\n"); }#endif /* So we don't have to call __hash() each time */ for (i = 0; i < win->maxx; i++) { buf[i].ch = ' '; buf[i].attr = 0; } blank_hash = __hash((char *) buf, win->maxx * __LDATASIZE); /* * Perform the rotation to maintain the consistency of curscr. * This is hairy since we are doing an *in place* rotation. * Invariants of the loop: * - I is the index of the current line. * - Target is the index of the target of line i. * - Tmp1 points to current line (i). * - Tmp2 and points to target line (target); * - Cur_period is the index of the end of the current period. * (see below). * * There are 2 major issues here that make this rotation non-trivial: * 1. Scrolling in a scrolling region bounded by the top * and bottom regions determined (whose size is sc_region). * 2. As a result of the use of the mod function, there may be a * period introduced, i.e., 2 maps to 4, 4 to 6, n-2 to 0, and * 0 to 2, which then causes all odd lines not to be rotated. * To remedy this, an index of the end ( = beginning) of the * current 'period' is kept, cur_period, and when it is reached, * the next period is started from cur_period + 1 which is * guaranteed not to have been reached since that would mean that * all records would have been reached. (think about it...). * * Lines in the rotation can have 3 attributes which are marked on the * line so that curscr is consistent with the visual screen. * 1. Not dirty -- lines inside the scrolled block, top region or * bottom region. * 2. Blank lines -- lines in the differential of the scrolling * region adjacent to top and bot regions * depending on scrolling direction. * 3. Dirty line -- all other lines are marked dirty. */ sc_region = bot - top + 1; i = top; tmp1 = curscr->lines[top]; cur_period = top; for (j = top; j <= bot; j++) { target = (i - top + n + sc_region) % sc_region + top; tmp2 = curscr->lines[target]; curscr->lines[target] = tmp1; /* Mark block as clean and blank out scrolled lines. */ clp = curscr->lines[target];#ifdef DEBUG __CTRACE("quickch: n=%d startw=%d curw=%d i = %d target=%d ", n, startw, curw, i, target);#endif if ((target >= startw && target < curw) || target < top || target > bot) {#ifdef DEBUG __CTRACE("-- notdirty");#endif win->lines[target]->flags &= ~__ISDIRTY; } else if ((n > 0 && target >= top && target < top + n) || (n < 0 && target <= bot && target > bot + n)) { if (clp->hash != blank_hash || memcmp(clp->line, buf, win->maxx * __LDATASIZE) !=0) { (void)memcpy(clp->line, buf, win->maxx * __LDATASIZE);#ifdef DEBUG __CTRACE("-- blanked out: dirty");#endif clp->hash = blank_hash; __touchline(win, target, 0, win->maxx - 1, 0); } else { __touchline(win, target, 0, win->maxx - 1, 0);#ifdef DEBUG __CTRACE(" -- blank line already: dirty");#endif } } else {#ifdef DEBUG __CTRACE(" -- dirty");#endif __touchline(win, target, 0, win->maxx - 1, 0); }#ifdef DEBUG __CTRACE("\n");#endif if (target == cur_period) { i = target + 1; tmp1 = curscr->lines[i]; cur_period = i; } else { tmp1 = tmp2; i = target; } }#ifdef DEBUG __CTRACE("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); for (i = 0; i < curscr->maxy; i++) { __CTRACE("C: %d:", i); for (j = 0; j < curscr->maxx; j++) __CTRACE("%c", curscr->lines[i]->line[j].ch); __CTRACE("\n"); __CTRACE("W: %d:", i); for (j = 0; j < win->maxx; j++) __CTRACE("%c", win->lines[i]->line[j].ch); __CTRACE("\n"); }#endif if (n != 0) { WINDOW *wp; scrolln(win, starts, startw, curs, bot, top); /* * Need to repoint any subwindow lines to the rotated * line structured. */ for (wp = win->nextp; wp != win; wp = wp->nextp) __set_subwin(win, wp); }}/* * Scrolln performs the scroll by n lines, where n is starts - startw. */static voidscrolln(win, starts, startw, curs, bot, top) WINDOW *win; int starts, startw, curs, bot, top;{ int i, oy, ox, n; oy = curscr->cury; ox = curscr->curx; n = starts - startw; if (n > 0) { __mvcur(oy, ox, top, 0, 1); /* Scroll up the block */ if (DL) tputs(__tscroll(DL, n), 0, __cputchar); else for(i = 0; i < n; i++) tputs(dl, 0, __cputchar); /* * Push down the bottom region. */ __mvcur(top, 0, bot - n + 1, 0, 1); if (AL) tputs(__tscroll(AL, n), 0, __cputchar); else for(i = 0; i < n; i++) tputs(al, 0, __cputchar); __mvcur(bot - n + 1, 0, oy, ox, 1); } else { /* Preserve the bottom lines */ __mvcur(oy, ox, bot + n + 1, 0, 1); /* n < 0 */ if (DL) tputs(__tscroll(DL, -n), 0, __cputchar); else for(i = n; i < 0; i++) tputs(dl, 0, __cputchar); __mvcur(bot + n + 1, 0, top, 0, 1); /* Scroll the block down */ if (AL) tputs(__tscroll(AL, -n), 0, __cputchar); else for(i = n; i < 0; i++) tputs(al, 0, __cputchar); __mvcur(top, 0, oy, ox, 1); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -