📄 screen.c
字号:
oldviewstart = r->TermWin.view_start; if (y < len) { p = (r->TermWin.nrow + r->TermWin.nscrolled) * (len - y) / len; p -= (long)(r->TermWin.nrow - 1); p = max(p, 0); } r->TermWin.view_start = (u_int16_t)min(p, r->TermWin.nscrolled); D_SCREEN((stderr, "rxvt_scr_move_to(%d, %d) view_start:%d", y, len, r->TermWin.view_start)); return rxvt_scr_changeview(r, oldviewstart);}/* ------------------------------------------------------------------------- *//* * Page the screen up/down nlines * direction should be UP or DN *//* EXTPROTO */intrxvt_scr_page(rxvt_t *r, enum page_dirn direction, int nlines){ int n; u_int16_t oldviewstart; D_SCREEN((stderr, "rxvt_scr_page(%s, %d) view_start:%d", ((direction == UP) ? "UP" : "DN"), nlines, r->TermWin.view_start));#ifdef DEBUG_STRICT assert((nlines >= 1) && (nlines <= r->TermWin.nrow));#endif oldviewstart = r->TermWin.view_start; if (direction == UP) { n = r->TermWin.view_start + nlines; r->TermWin.view_start = min(n, r->TermWin.nscrolled); } else { n = r->TermWin.view_start - nlines; r->TermWin.view_start = max(n, 0); } return rxvt_scr_changeview(r, oldviewstart);}/* INTPROTO */intrxvt_scr_changeview(rxvt_t *r, u_int16_t oldviewstart){ if (r->TermWin.view_start != oldviewstart) { r->h->want_refresh = 1; if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, 0); r->h->num_scr -= (r->TermWin.view_start - oldviewstart); } return (int)(r->TermWin.view_start - oldviewstart);}/* ------------------------------------------------------------------------- *//* EXTPROTO */voidrxvt_scr_bell(rxvt_t *r){#ifndef NO_BELL# ifndef NO_MAPALERT# ifdef MAPALERT_OPTION if (r->Options & Opt_mapAlert)# endif XMapWindow(r->Xdisplay, r->TermWin.parent[0]);# endif if (r->Options & Opt_visualBell) { rxvt_scr_rvideo_mode(r, !r->h->rvideo); /* refresh also done */ rxvt_scr_rvideo_mode(r, !r->h->rvideo); /* refresh also done */ } else XBell(r->Xdisplay, 0);#endif}/* ------------------------------------------------------------------------- *//* ARGSUSED *//* EXTPROTO */voidrxvt_scr_printscreen(rxvt_t *r, int fullhist){#ifdef PRINTPIPE int i, r1, nrows, row_offset; text_t *t; FILE *fd; if ((fd = rxvt_popen_printer(r)) == NULL) return; nrows = r->TermWin.nrow; row_offset = r->TermWin.saveLines; if (!fullhist) row_offset -= r->TermWin.view_start; else { nrows += r->TermWin.nscrolled; row_offset -= r->TermWin.nscrolled; } for (r1 = 0; r1 < nrows; r1++) { t = r->screen.text[r1 + row_offset]; for (i = r->TermWin.ncol - 1; i >= 0; i--) if (!isspace(t[i])) break; fprintf(fd, "%.*s\n", (i + 1), t); } rxvt_pclose_printer(fd);#endif}/* ------------------------------------------------------------------------- *//* * Refresh the screen * r->drawn_text/r->drawn_rend contain the screen information before the update. * r->screen.text/r->screen.rend contain what the screen will change to. */#define DRAW_STRING(Func, x, y, str, len) \ Func(r->Xdisplay, drawBuffer, r->TermWin.gc, (x), (y), (str), (len))#if defined (NO_BRIGHTCOLOR) || defined (VERYBOLD)# define MONO_BOLD(x) ((x) & (RS_Bold|RS_Blink))# define MONO_BOLD_FG(x, fg) MONO_BOLD(x)#else# define MONO_BOLD(x) \ (((x) & (RS_Bold | RS_fgMask)) == (RS_Bold | Color_fg))# define MONO_BOLD_FG(x, fg) (((x) & RS_Bold) && (fg) == Color_fg)#endif#define FONT_WIDTH(X, Y) \ (X)->per_char[(Y) - (X)->min_char_or_byte2].width#define FONT_RBEAR(X, Y) \ (X)->per_char[(Y) - (X)->min_char_or_byte2].rbearing#define FONT_LBEAR(X, Y) \ (X)->per_char[(Y) - (X)->min_char_or_byte2].lbearing#define IS_FONT_CHAR(X, Y) \ ((Y) >= (X)->min_char_or_byte2 && (Y) <= (X)->max_char_or_byte2)/* EXTPROTO */voidrxvt_scr_refresh(rxvt_t *r, unsigned char refresh_type){ unsigned char clearfirst, /* first character writes before cell */ clearlast, /* last character writes beyond cell */ must_clear, /* use draw_string not draw_image_string */#ifndef NO_BOLDFONT bfont, /* we've changed font to bold font */#endif rvid, /* reverse video this position */ wbyte; /* we're in multibyte */ char morecur = 0;/* */#ifdef TTY_256COLOR u_int16_t fore, back; /* desired foreground/background */#else unsigned char fore, back; /* desired foreground/background */#endif int16_t col, row, /* column/row we're processing */ ocrow, /* old cursor row */ len, wlen; /* text length screen/buffer */ int i, /* tmp */ row_offset; /* basic offset in screen structure */#ifndef NO_CURSORCOLOR rend_t cc1; /* store colours at cursor position(s) */# ifdef MULTICHAR_SET rend_t cc2; /* store colours at cursor position(s) */# endif#endif XGCValues gcvalue; /* Graphics Context values */ rend_t *drp, *srp; /* drawn-rend-pointer, screen-rend-pointer */ text_t *dtp, *stp; /* drawn-text-pointer, screen-text-pointer */ char *buffer; /* local copy of r->h->buffer */ struct rxvt_hidden *h = r->h; int (*draw_string) () = XDrawString; int (*draw_image_string) () = XDrawImageString; if (refresh_type == NO_REFRESH || !r->TermWin.mapped) return;/* * A: set up vars */ clearfirst = clearlast = must_clear = wbyte = 0;#ifndef NO_BOLDFONT bfont = 0;#endif if (h->currmaxcol < r->TermWin.ncol) { h->currmaxcol = r->TermWin.ncol; h->buffer = rxvt_realloc(h->buffer, sizeof(char) * (h->currmaxcol + 1)); } buffer = h->buffer; h->refresh_count = 0; row_offset = r->TermWin.saveLines - r->TermWin.view_start;/* * always go back to the base font - it's much safer */ XSetFont(r->Xdisplay, r->TermWin.gc, r->TermWin.font->fid); if ((refresh_type & REFRESH_BOUNDS)) { clearfirst = clearlast = 1; h->refresh_type &= ~REFRESH_BOUNDS; }#if defined(XPM_BACKGROUND) must_clear |= (h->bgPixmap.pixmap != None);#endif#if defined(TRANSPARENT) must_clear |= ((r->Options & Opt_transparent) && h->am_transparent);#endif ocrow = h->oldcursor.row; /* is there an old outline cursor on screen? */ /* set base colours to avoid check in "single glyph writing" below */ gcvalue.foreground = r->PixColors[Color_fg]; gcvalue.background = r->PixColors[Color_bg];/* * B: reverse any characters which are selected */ rxvt_scr_reverse_selection(r);/* * C: set the cursor character(s) */ { unsigned char setoldcursor; rend_t ccol1, /* Cursor colour */ ccol2; /* Cursor colour2 */ if ((r->screen.flags & Screen_VisibleCursor) && r->TermWin.focus) { srp = &(r->screen.rend[r->screen.cur.row + r->TermWin.saveLines] [r->screen.cur.col]); *srp ^= RS_RVid;#ifndef NO_CURSORCOLOR cc1 = *srp & (RS_fgMask | RS_bgMask); if (XDEPTH > 2 && ISSET_PIXCOLOR(h, Color_cursor)) ccol1 = Color_cursor; else#ifdef CURSOR_COLOR_IS_RENDITION_COLOR ccol1 = GET_FGCOLOR(h->rstyle);#else ccol1 = Color_fg;#endif if (XDEPTH > 2 && ISSET_PIXCOLOR(h, Color_cursor)) ccol2 = Color_cursor2; else#ifdef CURSOR_COLOR_IS_RENDITION_COLOR ccol2 = GET_BGCOLOR(h->rstyle);#else ccol2 = Color_bg;#endif *srp = SET_FGCOLOR(*srp, ccol1); *srp = SET_BGCOLOR(*srp, ccol2);#endif#ifdef MULTICHAR_SET if (IS_MULTI1(*srp)) { if (r->screen.cur.col < r->TermWin.ncol - 2 && IS_MULTI2(*++srp)) morecur = 1; } else if (IS_MULTI2(*srp)) { if (r->screen.cur.col > 0 && IS_MULTI1(*--srp)) morecur = -1; } if (morecur) { *srp ^= RS_RVid;# ifndef NO_CURSORCOLOR cc2 = *srp & (RS_fgMask | RS_bgMask); *srp = SET_FGCOLOR(*srp, ccol1); *srp = SET_BGCOLOR(*srp, ccol2);# endif }#endif } /* make sure no outline cursor is left around */ setoldcursor = 0; if (ocrow != -1) { if (r->screen.cur.row + r->TermWin.view_start != ocrow || r->screen.cur.col != h->oldcursor.col) { if (ocrow < r->TermWin.nrow && h->oldcursor.col < r->TermWin.ncol) { r->drawn_rend[ocrow][h->oldcursor.col] ^= (RS_RVid | RS_Uline);#ifdef MULTICHAR_SET if (h->oldcursormulti) { col = h->oldcursor.col + h->oldcursormulti; if (col < r->TermWin.ncol) r->drawn_rend[ocrow][col] ^= (RS_RVid | RS_Uline); }#endif } if (r->TermWin.focus || !(r->screen.flags & Screen_VisibleCursor)) h->oldcursor.row = -1; else setoldcursor = 1; } } else if (!r->TermWin.focus) setoldcursor = 1; if (setoldcursor) { if (r->screen.cur.row + r->TermWin.view_start >= r->TermWin.nrow) h->oldcursor.row = -1; else { h->oldcursor.row = r->screen.cur.row + r->TermWin.view_start; h->oldcursor.col = r->screen.cur.col;#ifdef MULTICHAR_SET h->oldcursormulti = morecur;#endif } } }#ifndef NO_SLOW_LINK_SUPPORT/* * D: CopyArea pass - very useful for slower links * This has been deliberately kept simple. */ i = h->num_scr; if (refresh_type == FAST_REFRESH && h->num_scr_allow && i && abs(i) < r->TermWin.nrow && !must_clear) { int16_t nits; int j; rend_t *drp2; text_t *dtp2; j = r->TermWin.nrow; wlen = len = -1; row = i > 0 ? 0 : j - 1; for (; j-- >= 0; row += (i > 0 ? 1 : -1)) { if (row + i >= 0 && row + i < r->TermWin.nrow && row + i != ocrow) { stp = r->screen.text[row + row_offset]; srp = r->screen.rend[row + row_offset]; dtp = r->drawn_text[row]; dtp2 = r->drawn_text[row + i]; drp = r->drawn_rend[row]; drp2 = r->drawn_rend[row + i]; for (nits = 0, col = r->TermWin.ncol; col--; ) if (stp[col] != dtp2[col] || srp[col] != drp2[col]) nits--; else if (stp[col] != dtp[col] || srp[col] != drp[col]) nits++; if (nits > 8) { /* XXX: arbitrary choice */ for (col = r->TermWin.ncol; col--; ) { *dtp++ = *dtp2++; *drp++ = *drp2++; } if (len == -1) len = row; wlen = row; continue; } } if (len != -1) { /* also comes here at end if needed because of >= above */ if (wlen < len) SWAP_IT(wlen, len, int); D_SCREEN((stderr, "rxvt_scr_refresh(): XCopyArea: %d -> %d (height: %d)", len + i, len, wlen - len + 1)); XCopyArea(r->Xdisplay, r->TermWin.vt, r->TermWin.vt, r->TermWin.gc, 0, Row2Pixel(len + i), (unsigned int)TermWin_TotalWidth(), (unsigned int)Height2Pixel(wlen - len + 1), 0, Row2Pixel(len)); len = -1; } } }#endif/* * E: main pass across every character */ for (row = 0; row < r->TermWin.nrow; row++) { unsigned char clear_next = 0; int j, xpixel, /* x offset for start of drawing (font) */ ypixel, /* y offset for start of drawing (font) */ ypixelc; /* y offset for top of drawing */ unsigned long gcmask; /* Graphics Context mask */ const XFontStruct *wf; /* which font are we in */ stp = r->screen.text[row + row_offset]; srp = r->screen.rend[row + row_offset]; dtp = r->drawn_text[row]; drp = r->drawn_rend[row];#ifndef NO_PIXEL_DROPPING_AVOIDANCE/* * E1: pixel dropping avoidance. Do this before the main refresh on the line. * Require a refresh where pixels may have been dropped into our * area by a neighbour character which has now changed * TODO: this could be integrated into E2 but might be too messy */# ifdef NO_BOLDFONT wf = r->TermWin.font;# endif for (col = 0; col < r->TermWin.ncol; col++) { unsigned char is_font_char, is_same_char; text_t t; t = dtp[col]; is_same_char = (t == stp[col] && drp[col] == srp[col]); if (!clear_next && (is_same_char || t == 0 /* screen cleared elsewhere */ || t == ' ')) continue; if (clear_next) { /* previous char caused change here */ clear_next = 0; dtp[col] = 0; if (is_same_char) /* don't cascade into next char */ continue; } j = MONO_BOLD(drp[col]) ? 1 : 0;# ifndef NO_BOLDFONT wf = (j && r->TermWin.boldFont) ? r->TermWin.boldFont : r->TermWin.font;# endif/* * TODO: consider if anything special needs to happen with: * #if defined(MULTICHAR_SET) && ! defined(NO_BOLDOVERSTRIKE_MULTI) */ is_font_char = (wf->per_char && IS_FONT_CHAR(wf, t)) ? 1 : 0; if (!is_font_char || FONT_LBEAR(wf, t) < 0) { if (col == 0) clearfirst = 1; else dtp[col - 1] = 0; } if (!is_font_char || (FONT_WIDTH(wf, t) < (FONT_RBEAR(wf, t) + j))) { if (col == r->TermWin.ncol - 1) clearlast = 1; else clear_next = 1; } }#endif /* NO_PIXEL_DROPPING_AVOIDANCE *//* * E2: OK, now the real pass */ ypixelc = (int)Row2Pixel(row); ypixel = ypixelc + r->TermWin.font->ascent; for (col = 0; col < r->TermWin.ncol; col++) { unsigned char fontdiff,/* current font size != base font size */ fpr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -