📄 wrefresh.c
字号:
/* Copyright (c) 1984 AT&T *//* All Rights Reserved *//* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T *//* The copyright notice above does not evidence any *//* actual or intended publication of such source code. */#ifndef lintstatic char sccsid[] = "@(#)wrefresh.c 1.1 92/07/30 SMI"; /* from S5R3.1 1.29 */#endif#include "curses_inc.h"/* * Make the screen look like "win" over the area covered by win. * This routine may use insert/delete char/line and scrolling-region. * win : the window being updated */extern int outchcount;void _updateln();static short cy, cx, /* current cursor coord */ scrli, /* actual screen lines */ scrco; /* actual screen columns */static char **marks; /* the mark table for cookie terminals */#define _ISMARK1(y, x) (marks[y][x / BITSPERBYTE] & (1 << (x % BITSPERBYTE)))#ifdef _VR2_COMPAT_CODEextern char _endwin;#endif /* _VR2_COMPAT_CODE */wrefresh(win)WINDOW *win;{ extern int _outch(); register short *bnsch, *ensch; register SLK_MAP *slk; int wx, wy, nc, boty, clby, idby, *hs, curwin; curwin = (win == curscr); /* don't allow curscr refresh if the screen was just created */ if (curwin && curscr->_sync) return (OK); /* go thru _stdbody */ if (!curwin && (win != _virtscr)) (void) wnoutrefresh(win); /* if there is typeahead and we're not forcing update */ if (!cur_term->_forceupdate && (_INPUTPENDING = _chkinput()) == TRUE) { if (curwin) curscr->_clear = TRUE; return (OK); } if (curwin || curscr->_clear) _virtscr->_clear = TRUE; /* save curscr cursor coordinates */ cy = curscr->_cury; cx = curscr->_curx; /* to simplify code in some cases */ marks = _MARKS; scrli = curscr->_maxy; scrco = curscr->_maxx; slk = SP->slk; outchcount = 0; /* make sure we're in program mode */ if (SP->fl_endwin) { /* If endwin is equal to 2 it means we just did a newscreen. */ if (SP->fl_endwin == TRUE) { reset_prog_mode(); if (SP->kp_state) tputs(keypad_xmit, 1, _outch); if (slk) (*_do_slk_tch)(); if (SP->fl_meta) tputs(meta_on, 1, _outch); if (cur_term->_cursorstate != 1) _PUTS(cur_term->cursor_seq[cur_term->_cursorstate], 0); } _PUTS(enter_ca_mode, 1); tputs(ena_acs, 1, _outch); if (exit_attribute_mode) _PUTS(exit_attribute_mode, 1); else /* * If there is no exit_attribute mode, then vidupdate * could only possibly turn off one of the below three * so that's all we ask it turn off. */ vidupdate(A_NORMAL, (A_ALTCHARSET | A_STANDOUT | A_UNDERLINE), _outch); SP->fl_endwin = FALSE;#ifdef _VR2_COMPAT_CODE _endwin = (char) FALSE;#endif /* _VR2_COMPAT_CODE */ } /* clear the screen if required */ if (_virtscr->_clear) { _PUTS(clear_screen, scrli); cy = cx = curscr->_curx = curscr->_cury = 0; /* _sync indicates that this a new screen */ if (!curscr->_sync) (void) werase(curscr); else { nc = scrco / BITSPERBYTE - (scrco % BITSPERBYTE ? 0 : 1); wy = scrli - 1; bnsch = _BEGNS; ensch = _ENDNS; hs = _CURHASH; for (; wy >= 0; --wy) { *bnsch++ = scrco; *ensch++ = -1; *hs++ = 0; if (marks) for(wx = nc; wx >= 0; --wx) marks[wy][wx] = 0; } } _virtscr->_clear = curscr->_sync = curscr->_clear = FALSE; if (slk) (*_do_slk_tch)(); /* pretend _virtscr has been totally changed */ (void) wtouchln(_virtscr, 0, scrli, -1); _VIRTTOP = 0; _VIRTBOT = scrli - 1; /* will not do clear-eod or ins/del lines */ clby = idby = scrli; } else clby = idby = -1; /* Software soft labels; if _changed == 2, slk's are in clear mode. */ if (slk && slk->_win && (slk->_changed == TRUE)) (*_do_slk_noref)(); /* do line updating */ _virtscr->_clear = FALSE; wy = _VIRTTOP; boty = _VIRTBOT + 1; bnsch = _virtscr->_firstch + wy; ensch = _virtscr->_lastch + wy; for(; wy < boty; ++wy, ++bnsch, ++ensch) { /* this line is up-to-date */ if (*bnsch >= scrco) goto next; /* we're not forcing update and there is type-ahead */ if (!curwin && !cur_term->_forceupdate && (_INPUTPENDING = _chkinput()) == TRUE) { _VIRTTOP = wy; goto done; } if (clby < 0) { /* now we have to work, check for ceod */ clby = _getceod(wy, boty); /* check for insert/delete lines */ if (_virtscr->_use_idl) idby = (*_setidln)(wy, boty); } /* try clear-to-eod */ if (wy == clby) _useceod(wy, boty); /* try ins/del lines */ if (wy == idby) { curscr->_cury = cy; curscr->_curx = cx; (*_useidln)(); cy = curscr->_cury; cx = curscr->_curx; } if (*bnsch < scrco) _updateln(wy);next: *bnsch = _INFINITY; *ensch = -1; } /* do hardware soft labels; if _changed == 2, slk's are in clear mode. */ if (slk && (slk->_changed == TRUE) && !(slk->_win)) (*_do_slk_ref)(); /* move cursor */ wy = _virtscr->_cury; wx = _virtscr->_curx; if (wy != cy || wx != cx) { (void) mvcur(cy, cx, wy, wx); cy = wy; cx = wx; } /* reset the flags */ curscr->_clear = FALSE; _virtscr->_use_idl = FALSE; _virtscr->_use_idc = TRUE; _INPUTPENDING = FALSE; /* virtual image is now up-to-date */ _VIRTTOP = scrli; _VIRTBOT = -1;done : curscr->_cury = cy; curscr->_curx = cx; (void) fflush(SP->term_file); return (outchcount);}/* Shift appropriate portions of a line to leave space for cookies. */static chtype *_shove(wy)register int wy;{ register chtype *wcp, *cp, prev; register int x, curx, cury, didshift; static chtype *line; static int length; /* allocate space for shifted line */ if (length < scrco) { if (line) free((char *) line); line = (chtype *) malloc(scrco * sizeof(chtype)); length = line ? scrco : 0; } /* no space to do it */ if (!line) return (_virtscr->_y[wy]); prev = A_NORMAL; cp = line; wcp = _virtscr->_y[wy]; curx = _virtscr->_curx; cury = _virtscr->_cury; didshift = FALSE; for (x = 0; x < scrco; ++x, ++wcp, ++cp) { if (_ATTR(*wcp) != prev) { /* use existing blank */ if (_CHAR(*wcp) == ' ') *cp = ' ' | _ATTR(*(wcp + 1)); /* use previous blank */ else if ((x > 0) && _CHAR(*(cp - 1)) == ' ') { *(cp - 1) = ' ' | _ATTR(*wcp); *cp = *wcp; } /* insert new blank */ else { if ((curx >= x) && (cury == wy)) ++curx; *cp = ' ' | _ATTR(*wcp); --wcp; didshift = TRUE; } prev = _ATTR(*cp); } else *cp = *wcp; } /* make sure that the end of the line is normal */ cp = line + scrco - 1; if (didshift || (_ATTR(*cp) != A_NORMAL) || ((wy == scrli - 1) && (_ATTR(*(cp - 1)) != A_NORMAL))) { *cp = didshift ? ' ' : _CHAR(*cp); if (wy == scrli - 1) *(cp - 1) = didshift ? ' ' : _CHAR(*(cp - 1)); } if (wy == cury) _virtscr->_curx = curx >= scrco ? scrco - 1 : curx; return (line);}/* * Update a line. * Three schemes of coloring are allowed. The first is the usual * pen-up/pen-down model. The second is the HP26*-like model. * In this case, colorings are specified by intervals, the left * side of the interval has the coloring mark, the right side * has the end-coloring mark. We assume that clear sequences will * clear ALL marks in the affected regions. The second case is * signified by the boolean flag ceol_standout_glitch. * The third case is for terminals that leave visible cookies on * the screen. This last case is at most an approximation of what * can be done right. */static void_updateln(wy)int wy;{ extern int _outch(); register chtype *wcp, *scp, *wp, *sp; register int wx, lastx, x; int mtch, idch, blnkx, idcx, attrx, maxi, endns, begns; bool redraw, changed, didattr; chtype wc, sc, sa; redraw = (_virtscr->_firstch[wy] == _REDRAW); endns = _ENDNS[wy]; begns = _BEGNS[wy]; /* easy case */ if (!redraw && (_virtscr->_lastch[wy] == _BLANK) && (begns >= scrco)) return; /* line images */ wcp = magic_cookie_glitch <= 0 ? _virtscr->_y[wy] : _shove(wy); scp = curscr->_y[wy]; /* the interval to be updated */ if (redraw || magic_cookie_glitch >= 0) { wx = 0; lastx = scrco; } else { wx = _virtscr->_firstch[wy]; lastx = _virtscr->_lastch[wy] == _BLANK ? scrco : _virtscr->_lastch[wy] + 1; } /* skip equal parts */ if (!redraw) { /* skip the starting equal part */ wp = wcp + wx; sp = scp + wx; for (; wx < lastx; ++wx) if (*wp++ != *sp++) break; if (wx >= lastx) return; /* skip the ending equal part */ wp = wcp + lastx - 1; sp = scp + lastx - 1; for (; lastx > wx; --lastx) if (*wp-- != *sp--) break; } /* place to do clear-eol */ if (!clr_eol || endns >= lastx) blnkx = scrco; else if (_virtscr->_lastch[wy] == _BLANK) blnkx = -1; else { for (blnkx = lastx - 1, wp = wcp + blnkx; blnkx >= wx; --blnkx, --wp) if (_DARKCHAR(*wp)) break; if (blnkx + _COST(Clr_eol) >= lastx) blnkx = scrco; } /* on cookie terminals, we may need to do more work */ if (marks) { if (blnkx < scrco) attrx = blnkx + 1; else { attrx = scrco; wp = wcp + attrx - 1; for (; attrx > lastx; --attrx, --wp) if (_ATTR(*wp) != A_NORMAL) break; lastx = attrx; if (attrx >= scrco) --attrx; if (magic_cookie_glitch > 0 && wy == scrli - 1 && attrx == scrco - 1) --attrx; } } /* place for insert/delete chars */#define SLACK 4 if (redraw || (!SP->dchok && !SP->ichok) || !(_virtscr->_use_idc) || endns < wx || (endns >= lastx && (scrco - lastx) > SLACK)) { idcx = scrco; } else if (!marks) idcx = -1; else { /* on cookie term, only do idch where no attrs are used */ for (idcx = scrco - 1, wp = wcp + idcx; idcx >= wx; --idcx, --wp) if (_ATTR(*wp) || _ISMARK1(wy, idcx)) break; if (idcx >= scrco - SLACK) idcx = scrco; } if (idcx < lastx && endns >= lastx) lastx = scrco; /* max amount of insert allow */ if (idcx == scrco || !SP->ichok) maxi = 0; else if (lastx == scrco) maxi = scrco; else maxi = lastx - (endns + 1); /* go */ wcp += wx; scp += wx; didattr = changed = FALSE; while (wx < lastx) { /* skip things that are already right */ if (!redraw) { for (; wx < lastx; ++wx, ++wcp, ++scp) if (*wcp != *scp) break; if (wx >= lastx) goto done; } /* try clear-bol, we'll assume exclusive clr_bol */ if (!changed && !marks && clr_bol && blnkx > wx && begns >= wx) { for (x = wx, wp = wcp; x < lastx; ++x, ++wp) if (_DARKCHAR(*wp)) break; x -= 1; if ((x - (redraw ? 0 : begns)) > _COST(Clr_bol)) { (void) mvcur(cy, cx, wy, x); _PUTS(clr_bol, 1); cy = wy; cx = x; mtch = x - wx; (void) memcpy((char *) scp, (char *) wcp, (int) (mtch * sizeof(chtype))); wcp += mtch; scp += mtch; wx = x; } } /* screen image is changing */ changed = TRUE; /* move to the point to start refresh */ if (cy != wy || cx != wx) (void) mvcur(cy, cx, wy, wx); cy = wy; cx = wx; /* update screen image */ while (wx < lastx) { wc = *wcp; sc = *scp; if (!redraw && wc == sc) break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -