📄 screen.c
字号:
free(r->buf_rend); free(r->tabs);/* NULL these so if anything tries to use them, we'll know about it */ r->screen.text = r->drawn_text = r->swap.text = NULL; r->screen.rend = r->drawn_rend = r->swap.rend = NULL; r->screen.tlen = r->swap.tlen = NULL; r->buf_text = NULL; r->buf_rend = NULL; r->tabs = NULL;}/* ------------------------------------------------------------------------- *//* * Hard reset *//* EXTPROTO */voidrxvt_scr_poweron(rxvt_t *r){ D_SCREEN((stderr, "rxvt_scr_poweron()")); rxvt_scr_release(r); r->h->prev_nrow = r->h->prev_ncol = 0; rxvt_scr_reset(r); rxvt_scr_clear(r); rxvt_scr_refresh(r, SLOW_REFRESH); rxvt_Gr_reset(r);}/* ------------------------------------------------------------------------- * * PROCESS SCREEN COMMANDS * * ------------------------------------------------------------------------- *//* * Save and Restore cursor * XTERM_SEQ: Save cursor : ESC 7 * XTERM_SEQ: Restore cursor: ESC 8 *//* EXTPROTO */voidrxvt_scr_cursor(rxvt_t *r, int mode){ screen_t *s; D_SCREEN((stderr, "rxvt_scr_cursor(%c)", mode));#if NSCREENS && !defined(NO_SECONDARY_SCREEN_CURSOR) if (r->h->current_screen == SECONDARY) s = &(r->swap); else#endif s = &(r->screen); switch (mode) { case SAVE: s->s_cur.row = s->cur.row; s->s_cur.col = s->cur.col; s->s_rstyle = r->h->rstyle; s->s_charset = s->charset; s->s_charset_char = r->h->charsets[s->charset]; break; case RESTORE: r->h->want_refresh = 1; s->cur.row = s->s_cur.row; s->cur.col = s->s_cur.col; s->flags &= ~Screen_WrapNext; r->h->rstyle = s->s_rstyle; s->charset = s->s_charset; r->h->charsets[s->charset] = s->s_charset_char; rxvt_set_font_style(r); break; }/* boundary check in case screen size changed between SAVE and RESTORE */ MIN_IT(s->cur.row, r->TermWin.nrow - 1); MIN_IT(s->cur.col, r->TermWin.ncol - 1);#ifdef DEBUG_STRICT assert(s->cur.row >= 0); assert(s->cur.col >= 0);#else /* drive with your eyes closed */ MAX_IT(s->cur.row, 0); MAX_IT(s->cur.col, 0);#endif}/* ------------------------------------------------------------------------- *//* * Swap between primary and secondary screens * XTERM_SEQ: Primary screen : ESC [ ? 4 7 h * XTERM_SEQ: Secondary screen: ESC [ ? 4 7 l *//* EXTPROTO */intrxvt_scr_change_screen(rxvt_t *r, int scrn){ int i;#if NSCREENS int offset;#endif r->h->want_refresh = 1; D_SCREEN((stderr, "rxvt_scr_change_screen(%d)", scrn)); r->TermWin.view_start = 0; RESET_CHSTAT(r->h); if (r->h->current_screen == scrn) return r->h->current_screen; rxvt_selection_check(r, 2); /* check for boundary cross */ SWAP_IT(r->h->current_screen, scrn, int);#if NSCREENS r->h->num_scr = 0; offset = r->TermWin.saveLines; for (i = r->h->prev_nrow; i--;) { SWAP_IT(r->screen.text[i + offset], r->swap.text[i], text_t *); SWAP_IT(r->screen.tlen[i + offset], r->swap.tlen[i], int16_t); SWAP_IT(r->screen.rend[i + offset], r->swap.rend[i], rend_t *); } SWAP_IT(r->screen.cur.row, r->swap.cur.row, int16_t); SWAP_IT(r->screen.cur.col, r->swap.cur.col, int16_t);# ifdef DEBUG_STRICT assert((r->screen.cur.row >= 0) && (r->screen.cur.row < r->h->prev_nrow)); assert((r->screen.cur.col >= 0) && (r->screen.cur.col < r->h->prev_ncol));# else /* drive with your eyes closed */ MAX_IT(r->screen.cur.row, 0); MIN_IT(r->screen.cur.row, r->h->prev_nrow - 1); MAX_IT(r->screen.cur.col, 0); MIN_IT(r->screen.cur.col, r->h->prev_ncol - 1);# endif SWAP_IT(r->screen.charset, r->swap.charset, int16_t); SWAP_IT(r->screen.flags, r->swap.flags, int); r->screen.flags |= Screen_VisibleCursor; r->swap.flags |= Screen_VisibleCursor; if (rxvt_Gr_Displayed(r)) { rxvt_Gr_scroll(r, 0); rxvt_Gr_ChangeScreen(r); }#else# ifdef SCROLL_ON_NO_SECONDARY if (rxvt_Gr_Displayed(r)) rxvt_Gr_ClearScreen(r); if (r->h->current_screen == PRIMARY && !rxvt_Gr_Displayed(r)) rxvt_scroll_text(r, 0, (r->h->prev_nrow - 1), r->h->prev_nrow, 0);# endif#endif return scrn;}/* ------------------------------------------------------------------------- *//* * Change the colour for following text *//* EXTPROTO */voidrxvt_scr_color(rxvt_t *r, unsigned int color, int fgbg){ color &= RS_fgMask; if (fgbg == Color_fg) r->h->rstyle = SET_FGCOLOR(r->h->rstyle, color); else r->h->rstyle = SET_BGCOLOR(r->h->rstyle, color);}/* ------------------------------------------------------------------------- *//* * Change the rendition style for following text *//* EXTPROTO */voidrxvt_scr_rendition(rxvt_t *r, int set, int style){ if (set) r->h->rstyle |= style; else if (style == ~RS_None) r->h->rstyle = DEFAULT_RSTYLE | (r->h->rstyle & RS_fontMask); else r->h->rstyle &= ~style;}/* ------------------------------------------------------------------------- *//* * Scroll text between <row1> and <row2> inclusive, by <count> lines * count positive ==> scroll up * count negative ==> scroll down * spec == 0 for normal routines *//* EXTPROTO */intrxvt_scroll_text(rxvt_t *r, int row1, int row2, int count, int spec){ int i, j; long nscrolled; if (count == 0 || (row1 > row2)) return 0; r->h->want_refresh = 1; D_SCREEN((stderr, "rxvt_scroll_text(%d,%d,%d,%d): %s", row1, row2, count, spec, (r->h->current_screen == PRIMARY) ? "Primary" : "Secondary")); if ((count > 0) && (row1 == 0) && (r->h->current_screen == PRIMARY)) { nscrolled = (long)r->TermWin.nscrolled + (long)count;; if (nscrolled > (long)r->TermWin.saveLines) r->TermWin.nscrolled = r->TermWin.saveLines; else r->TermWin.nscrolled = (u_int16_t)nscrolled; if ((r->Options & Opt_scrollWithBuffer) && r->TermWin.view_start != 0 && r->TermWin.view_start != r->TermWin.saveLines) rxvt_scr_page(r, UP, count); } else if (!spec) row1 += r->TermWin.saveLines; row2 += r->TermWin.saveLines; if (r->selection.op && r->h->current_screen == r->selection.screen) { i = r->selection.beg.row + r->TermWin.saveLines; j = r->selection.end.row + r->TermWin.saveLines; if ((i < row1 && j > row1) || (i < row2 && j > row2) || (i - count < row1 && i >= row1) || (i - count > row2 && i <= row2) || (j - count < row1 && j >= row1) || (j - count > row2 && j <= row2)) { CLEAR_ALL_SELECTION(r); r->selection.op = SELECTION_CLEAR; /* XXX: too aggressive? */ } else if (j >= row1 && j <= row2) { /* move selected region too */ r->selection.beg.row -= count; r->selection.end.row -= count; r->selection.mark.row -= count; } } rxvt_selection_check(r, 0); /* _after_ r->TermWin.nscrolled update */ r->h->num_scr += count; j = count; if (count < 0) count = -count; i = row2 - row1 + 1; MIN_IT(count, i); if (j > 0) {/* A: scroll up *//* A1: Copy lines that will get clobbered by the rotation */ for (i = 0, j = row1; i < count; i++, j++) { r->buf_text[i] = r->screen.text[j]; r->buf_rend[i] = r->screen.rend[j]; }/* A2: Rotate lines */ for (j = row1, i = j + count; i <= row2; i++, j++) { r->screen.tlen[j] = r->screen.tlen[i]; r->screen.text[j] = r->screen.text[i]; r->screen.rend[j] = r->screen.rend[i]; } j = row2 - count + 1, i = count; } else /* if (j < 0) */ {/* B: scroll down *//* B1: Copy lines that will get clobbered by the rotation */ for (i = 0, j = row2; i < count; i++, j--) { r->buf_text[i] = r->screen.text[j]; r->buf_rend[i] = r->screen.rend[j]; }/* B2: Rotate lines */ for (j = row2, i = j - count; i >= row1; i--, j--) { r->screen.tlen[j] = r->screen.tlen[i]; r->screen.text[j] = r->screen.text[i]; r->screen.rend[j] = r->screen.rend[i]; } j = row1, i = count; count = -count; }/* C: Resurrect lines */ for (; i--; j++) { r->screen.tlen[j] = 0; r->screen.text[j] = r->buf_text[i]; r->screen.rend[j] = r->buf_rend[i]; if (!spec) /* line length may not equal TermWin.ncol */ rxvt_blank_screen_mem(r, r->screen.text, r->screen.rend, (unsigned int)j, r->h->rstyle); } if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, count); return count;}/* ------------------------------------------------------------------------- *//* * Add text given in <str> of length <len> to screen struct *//* EXTPROTO */voidrxvt_scr_add_lines(rxvt_t *r, const unsigned char *str, int nlines, int len){ unsigned char checksel, clearsel; char c; int i, row, last_col; text_t *stp; rend_t *srp; struct rxvt_hidden *h = r->h; if (len <= 0) /* sanity */ return; h->want_refresh = 1; last_col = r->TermWin.ncol; D_SCREEN((stderr, "rxvt_scr_add_lines(%d,%d)", nlines, len)); ZERO_SCROLLBACK(r); if (nlines > 0) { nlines += (r->screen.cur.row - r->screen.bscroll); if ((nlines > 0) && (r->screen.tscroll == 0) && (r->screen.bscroll == (r->TermWin.nrow - 1))) { /* _at least_ this many lines need to be scrolled */ rxvt_scroll_text(r, r->screen.tscroll, r->screen.bscroll, nlines, 0); r->screen.cur.row -= nlines; } }#ifdef DEBUG_STRICT assert(r->screen.cur.col < last_col); assert((r->screen.cur.row < r->TermWin.nrow) && (r->screen.cur.row >= -(int32_t)r->TermWin.nscrolled));#else /* drive with your eyes closed */ MIN_IT(r->screen.cur.col, last_col - 1); MIN_IT(r->screen.cur.row, r->TermWin.nrow - 1); MAX_IT(r->screen.cur.row, -(int32_t)r->TermWin.nscrolled);#endif row = r->screen.cur.row + r->TermWin.saveLines; checksel = (r->selection.op && h->current_screen == r->selection.screen) ? 1 : 0; clearsel = 0; stp = r->screen.text[row]; srp = r->screen.rend[row];#ifdef MULTICHAR_SET if (h->lost_multi && r->screen.cur.col > 0 && IS_MULTI1(srp[r->screen.cur.col - 1]) && *str != '\n' && *str != '\r' && *str != '\t') h->chstat = WBYTE;#endif for (i = 0; i < len;) { c = str[i++]; switch (c) { case '\t': rxvt_scr_tab(r, 1); continue; case '\n': if (r->screen.tlen[row] != -1) /* XXX: think about this */ MAX_IT(r->screen.tlen[row], r->screen.cur.col); r->screen.flags &= ~Screen_WrapNext; if (r->screen.cur.row == r->screen.bscroll) rxvt_scroll_text(r, r->screen.tscroll, r->screen.bscroll, 1, 0); else if (r->screen.cur.row < (r->TermWin.nrow - 1)) row = (++r->screen.cur.row) + r->TermWin.saveLines; stp = r->screen.text[row]; /* _must_ refresh */ srp = r->screen.rend[row]; /* _must_ refresh */ RESET_CHSTAT(h); continue; case '\r': if (r->screen.tlen[row] != -1) /* XXX: think about this */ MAX_IT(r->screen.tlen[row], r->screen.cur.col); r->screen.flags &= ~Screen_WrapNext; r->screen.cur.col = 0; RESET_CHSTAT(h); continue; default:#ifdef MULTICHAR_SET if (r->encoding_method == NOENC) { if (c == 127) continue; break; } h->rstyle &= ~RS_multiMask; if (h->chstat == WBYTE) { h->rstyle |= RS_multi2; /* multibyte 2nd byte */ h->chstat = SBYTE; if ((r->encoding_method == EUCJ) || (r->encoding_method == GB)) c |= 0x80; /* maybe overkill, but makes it selectable */ } else if (h->chstat == SBYTE) { if (h->multi_byte || (c & 0x80)) { /* multibyte 1st byte */ h->rstyle |= RS_multi1; h->chstat = WBYTE; if ((r->encoding_method == EUCJ) || (r->encoding_method == GB)) c |= 0x80; /* maybe overkill, but makes selectable */ } } else#endif if (c == 127) continue; /* yummmm..... */ break; } if (checksel /* see if we're writing within selection */ && !ROWCOL_IS_BEFORE(r->screen.cur, r->selection.beg) && ROWCOL_IS_BEFORE(r->screen.cur, r->selection.end)) { checksel = 0; clearsel = 1; } if (r->screen.flags & Screen_WrapNext) { r->screen.tlen[row] = -1; if (r->screen.cur.row == r->screen.bscroll) rxvt_scroll_text(r, r->screen.tscroll, r->screen.bscroll, 1, 0); else if (r->screen.cur.row < (r->TermWin.nrow - 1)) row = (++r->screen.cur.row) + r->TermWin.saveLines; stp = r->screen.text[row]; /* _must_ refresh */ srp = r->screen.rend[row]; /* _must_ refresh */ r->screen.cur.col = 0; r->screen.flags &= ~Screen_WrapNext; } if (r->screen.flags & Screen_Insert) rxvt_scr_insdel_chars(r, 1, INSERT);#ifdef MULTICHAR_SET if (IS_MULTI1(h->rstyle) && r->screen.cur.col > 0 && IS_MULTI1(srp[r->screen.cur.col - 1])) { stp[r->screen.cur.col - 1] = ' '; srp[r->screen.cur.col - 1] &= ~RS_multiMask; } else if (IS_MULTI2(h->rstyle) && r->screen.cur.col < (last_col - 1) && IS_MULTI2(srp[r->screen.cur.col + 1])) { stp[r->screen.cur.col + 1] = ' '; srp[r->screen.cur.col + 1] &= ~RS_multiMask; }#endif stp[r->screen.cur.col] = c; srp[r->screen.cur.col] = h->rstyle; if (r->screen.cur.col < (last_col - 1)) r->screen.cur.col++; else { r->screen.tlen[row] = last_col; if (r->screen.flags & Screen_Autowrap) r->screen.flags |= Screen_WrapNext; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -