📄 wrefresh.c
字号:
/* real video attributes */ if (marks) curscr->_attrs = _ATTR(sc); /* blanks only */ if (wx > blnkx) { _PUTS(clr_eol, 1); curscr->_curx = wx; curscr->_cury = wy; (void) wclrtoeol(curscr); if (marks && wx > 0 && _ATTR(*(scp - 1)) != A_NORMAL) { _VIDS(A_NORMAL, _ATTR(*(scp - 1))); _setmark(wy, wx, NULL); } goto done; } /* try insert/delete chars */ if (wx > idcx && (mtch = _useidch(wcp, scp, lastx - wx, maxi, &idch))) { maxi -= idch; wx += mtch; scp += mtch; wcp += mtch; break; } /* about to output chars, make sure insert mode is off */ if (SP->phys_irm) _OFFINSERT(); /* video attributes */ if (_ATTR(wc) != curscr->_attrs) { /* prevent spilling out of line */ if (marks && !didattr) { didattr = TRUE; if (!_ISMARK1(wy, attrx)) { (void) mvcur(wy, wx, wy, attrx); sc = _ATTR(curscr->_y[wy][attrx]); sa = curscr->_attrs; _VIDS(sc, ~sc); _setmark(wy, attrx, NULL); (void) mvcur(wy, attrx, wy, wx); curscr->_attrs = sa; } } _VIDS(_ATTR(wc), curscr->_attrs); /* mark the interval */ if (marks) _setmark(wy, wx, scp); } /* end-of-line */ if (wx == scrco - 1) { _rmargin(wc); goto done; } if (transparent_underline && erase_overstrike && _CHAR(wc) == '_') { _outch(' '); (void) mvcur(wy, wx + 1, wy, wx); } /* put out the character */ _outch(tilde_glitch && _CHAR(wc) == '~' ? '`' : wc); *scp++ = wc; wcp++; wx++; cx++; } }done: if (changed) { /* update the blank structure */ for (wx = 0, scp = curscr->_y[wy]; wx < scrco; ++wx, ++scp) if (_DARKCHAR(*scp)) break; _BEGNS[wy] = wx; if (wx == scrco) _ENDNS[wy] = -1; else { wx = scrco - 1; scp = curscr->_y[wy] + wx; for (; wx >= 0; --wx, --scp) if (_DARKCHAR(*scp)) break; _ENDNS[wy] = wx; } /* update the hash structure */ _CURHASH[wy] = _BEGNS[wy] < scrco ? _NOHASH : 0; } return;}/* * See if a left or right shift is apppropriate * This routine is called only if !cookie_glitch or no video attributes * are used in the affected part. * The main idea is to find a longest common substring which is a * prefix of one of 'wcp' or 'scp', then either delete or * insert depending on where the prefix is. * * wcp : what we want the screen to look like * scp : what the screen looks like now * length: the length to be updated * maxi: maximum possible insert amount * id; *id returns the amount of insert/delete * * Return the number of chars matched after the shift. */static_useidch(wcp, scp, length, maxi, id)chtype *wcp, *scp;int length, maxi, *id;{ extern int _outch(); register int x1, x2, blnk; register chtype wc; int idch, cost, cost_ich1, match; /* try deletion */ if (SP->dchok && _CHAR(*wcp) != ' ') { if ((match = _prefix(wcp, scp, length, length / 2, &idch)) > 0) cost = _COST(dcfixed) + (parm_dch ? _COST(Parm_dch) : _COST(Delete_character) * idch); else cost = _INFINITY; if (match >= cost) { if (SP->dmode) { if (SP->sid_equal) { if (!(SP->phys_irm)) _ONINSERT(); } else { if (SP->phys_irm) _OFFINSERT(); _PUTS(enter_delete_mode, 1); } } if (parm_dch) _PUTS(tparm(parm_dch, idch), 1); else for (x1 = 0; x1 < idch; ++x1) _PUTS(delete_character, 1); if (SP->dmode) { if (SP->eid_equal) SP->phys_irm = FALSE; _PUTS(exit_delete_mode, 1); } /* update screen image */ for (x1 = 0, x2 = idch; x2 < length; ++x1, ++x2) scp[x1] = scp[x2]; for (; x1 < length; ++x1) scp[x1] = ' '; *id = -idch; return (match); } } /* no insertion wanted or possible */ if (!(SP->ichok) || _CHAR(*scp) == ' ') return (0); /* see if insertion is worth it */ maxi = (idch = length / 2) < maxi ? idch : maxi; if ((match = _prefix(scp, wcp, length, maxi, &idch)) <= 0) return (0); /* see if inserting blanks only */ for (blnk = 0; blnk < idch; ++blnk) if (wcp[blnk] != ' ') { blnk = 0; break; } /* see if doing insertion is worth it */ cost_ich1 = idch * _COST(Insert_character); if (SP->imode) { cost = SP->phys_irm ? 0 : _COST(icfixed); if (blnk > _COST(Parm_ich) && _COST(Parm_ich) < cost_ich1) cost += _COST(Parm_ich); else if (insert_character) cost += cost_ich1; } else { if (parm_ich && _COST(Parm_ich) < cost_ich1) cost = _COST(Parm_ich); else cost = cost_ich1; } if ((cost - blnk) > match) return (0); /* perform the insertions */ if (SP->imode) { if (!SP->phys_irm) _ONINSERT(); if (blnk > _COST(Parm_ich) && _COST(Parm_ich) < cost_ich1) _PUTS(tparm(parm_ich, idch), 1); else if (insert_character) goto do_insert_char; else /* so that we'll do real char insertions */ blnk = 0; } else { if (parm_ich && _COST(Parm_ich) < cost_ich1) _PUTS(tparm(parm_ich, idch), 1); else {do_insert_char: for (x1 = 0; x1 < idch; ++x1) _PUTS(insert_character, 1); } } /* inserting desired characters */ if (!blnk) for(x1 = 0; x1 < idch; ++x1) { wc = wcp[x1]; if (_ATTR(wc) != curscr->_attrs) _VIDS(_ATTR(wc),curscr->_attrs); _outch(_CHAR(wc) == '~' && tilde_glitch ? '`' : wc); ++cx; } /* update the screen image */ for (x1 = length - 1, x2 = length - idch - 1; x2 >= 0; --x1, --x2) scp[x1] = scp[x2]; (void) memcpy((char *) scp, (char *) wcp, idch * sizeof(chtype)); *id = idch; return (match + idch);}/* * Find a substring of s2 that match a prefix of s1. * The substring is such that: * 1. it does not start with an element * that is in perfect alignment with one in s1 and * 2: it is at least as long as the displacement. * * length: the length of s1, s2. * maxs: only search for match in [1,maxs] of s2. * begm: *begm returns where the match begins. * * Return the number of matches. */static_prefix(s1, s2, length, maxs, begm)chtype *s1, *s2;int length, maxs, *begm;{ register int m, n, k; n = 0; for (m = 1; m <= maxs; ++m) /* testing for s1[m] != s2[m] is condition 1 */ if (s1[0] == s2[m] && s1[m] != s2[m]) { /* see if it's long enough (condition 2) */ for (k = 2 * m - 1; k > m; --k) if (s1[k - m] != s2[k]) break; /* found a match with a good length */ if (k == m) { *begm = m; /* count the # of matches */ s2 += m; length -= m; for (n = m; n < length; ++n) if (s1[n] != s2[n]) break; goto done; } }done: return (n);}/* Set markers for cookie terminal. */static_setmark(y, x, s)int y, x;chtype *s;{ register int a; /* set the mark map */ marks[y][x / BITSPERBYTE] |= (1 << (x % BITSPERBYTE)); if (s) { a = _ATTR(curscr->_attrs); /* set the video attr of the first char here */ *s = _CHAR(*s) | a; /* now the video attr of the rest of the affected interval */ for (x += 1, s += 1; x < scrco; ++x, ++s) if (_ISMARK1(y, x)) break; else *s = _CHAR(*s) | a; }}/* At the right margin various weird things can happen. We treat them here. */static_rmargin(wc)chtype wc;{ extern int _outch(); register int x; chtype sc; x = scrco - 1; /* screen may scroll */ if (cy == scrli - 1) { /* can't do anything */ if (!SP->ichok) return; /* just one pos left of the bottom-right corner */ sc = curscr->_y[cy][x - 1]; (void) mvcur(cy, cx, cy, x - 1); _outch(tilde_glitch && _CHAR(wc) == '~' ? '`' : wc); /* insert sc back in and push wc right */ (void) mvcur(cy, x, cy, x - 1); if (SP->imode && !SP->phys_irm) _ONINSERT(); if (insert_character) _PUTS(insert_character, 1); else if (parm_ich && !SP->imode) _PUTS(tparm(parm_ich, 1), 1); if (_ATTR(sc) != curscr->_attrs) _VIDS(_ATTR(sc), curscr->_attrs); _outch(tilde_glitch && _CHAR(sc) == '~' ? '`' : sc); /* make sure the video attrs are ok */ if (marks && (_ATTR(sc) || _ATTR(wc))) _VIDS(_ATTR(wc), ~_ATTR(sc)); /* update screen image */ cx = x; curscr->_y[cy][x] = wc; return; } /* put char out and update screen image */ _outch(tilde_glitch && _CHAR(wc) == '~' ? '`' : wc); curscr->_y[cy][x] = wc; /* make sure that wrap-around happens */ if (!auto_right_margin || eat_newline_glitch) { _outch('\r'); _outch('\n'); } cx = 0; ++cy;}/* * Find the top-most line to do clear-to-eod. * * topy, boty: the region to consider */static_getceod(topy, boty)int topy, boty;{ register chtype *wcp, *ecp; register int wy; short *begch, *endch, *begns; /* do nothing */ if ((topy + 1) >= boty) return (boty); wy = boty - 1; begch = _virtscr->_firstch + wy; endch = _virtscr->_lastch + wy; begns = _BEGNS + wy; for (; wy >= topy; --wy, --begch, --endch, --begns) { if (*endch == _BLANK || (*begch >= scrco && *begns >= scrco)) continue; wcp = _virtscr->_y[wy]; ecp = wcp + scrco; for (; wcp < ecp; ++wcp) if (_DARKCHAR(*wcp)) break; if (wcp != ecp) break; *endch = _BLANK; } return (wy + 1);}/* Use hardware clear-to-bottom. */static_useceod(topy, boty)int topy, boty;{ extern int _outch(); register short *begns, *begch; /* skip lines already blanked */ begch = _virtscr->_firstch + topy; begns = _BEGNS + topy; for (; topy < boty; ++topy, ++begns, ++begch) if (*begns < scrco || *begch == _REDRAW) break; else *begch = _INFINITY; /* nothing to do */ if (topy + 1 >= boty) return; /* see if bottom is clear */ for (begns = _BEGNS + boty; boty < scrli; ++boty, ++begns) if (*begns < scrco) return; /* use clear-screen if appropriate */ if (topy == 0) { _PUTS(clear_screen, scrli); cy = 0; cx = 0; (void) werase(curscr); } /* use clear-to-end-of-display or delete lines */ else if (clr_eos || (parm_delete_line && !memory_below)) { (void) mvcur(cy, cx, topy, 0); cy = topy; cx = 0; _PUTS(clr_eos ? clr_eos : tparm(parm_delete_line, scrli - topy), scrli - topy); /* update curscr */ curscr->_cury = topy; (void) wclrtobot(curscr); } /* no hardware support */ else return; /* correct the update structure */ (void) wtouchln(_virtscr, topy, scrli, FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -