📄 screen.c
字号:
* Relative mode: line numbers are relative to top margin of scrolling region * and the cursor cannot be moved outside. * XTERM_SEQ: Set Absolute: ESC [ ? 6 h * XTERM_SEQ: Set Relative: ESC [ ? 6 l *//* EXTPROTO */voidrxvt_scr_relative_origin(rxvt_t* r, int page, int mode){ if (mode) PSCR(r, page).flags |= Screen_Relative; else PSCR(r, page).flags &= ~Screen_Relative; rxvt_scr_gotorc(r, page, 0, 0, 0);}/* ------------------------------------------------------------------------- *//* * Set insert/replace mode * XTERM_SEQ: Set Insert mode : ESC [ ? 4 h * XTERM_SEQ: Set Replace mode: ESC [ ? 4 l *//* EXTPROTO */voidrxvt_scr_insert_mode(rxvt_t* r, int page, int mode){ if (mode) PSCR(r, page).flags |= Screen_Insert; else PSCR(r, page).flags &= ~Screen_Insert;}/* ------------------------------------------------------------------------- *//* * Set/Unset tabs * XTERM_SEQ: Set tab at current column : ESC H * XTERM_SEQ: Clear tab at current column: ESC [ 0 g * XTERM_SEQ: Clear all tabs : ESC [ 3 g *//* EXTPROTO */voidrxvt_scr_set_tab(rxvt_t* r, int page, int mode){ if (mode < 0) MEMSET(r->tabstop, 0, r->TermWin.ncol * sizeof(char)); else if (PSCR(r, page).cur.col < r->TermWin.ncol) r->tabstop[PSCR(r, page).cur.col] = (mode ? 1 : 0);}/* ------------------------------------------------------------------------- *//* * Set reverse/normal video * XTERM_SEQ: Reverse video: ESC [ ? 5 h * XTERM_SEQ: Normal video : ESC [ ? 5 l *//* EXTPROTO */voidrxvt_scr_rvideo_mode(rxvt_t* r, int page, int mode){ if (PVTS(r, page)->rvideo != mode) { PVTS(r, page)->rvideo = mode; SWAP_IT(r->PixColors[Color_fg], r->PixColors[Color_bg], unsigned long);#if defined(BACKGROUND_IMAGE) if (PVTS(r, page)->bg.pixmap == None)#endif#if defined(TRANSPARENT) if (!(r->Options & Opt_transparent) || (!r->h->am_transparent && !r->h->am_pixmap_trans) )#endif XSetWindowBackground(r->Xdisplay, PVTS(r, page)->vt, r->PixColors[Color_bg]); XSetForeground (r->Xdisplay, r->TermWin.gc, r->PixColors[Color_fg]); XSetBackground (r->Xdisplay, r->TermWin.gc, r->PixColors[Color_bg]); rxvt_scr_clear(r, page); rxvt_scr_touch(r, page, True); }}/* ------------------------------------------------------------------------- *//* * Report current cursor position * XTERM_SEQ: Report position: ESC [ 6 n *//* EXTPROTO */voidrxvt_scr_report_position(rxvt_t* r, int page){ rxvt_tt_printf(r, page, "\033[%d;%dR", CURROW + 1, CURCOL + 1);}/* ------------------------------------------------------------------------- * * FONTS * * ------------------------------------------------------------------------- *//* * Set font style *//* INTPROTO */voidrxvt_set_font_style(rxvt_t *r, int page){ PVTS(r, page)->rstyle &= ~RS_fontMask; switch (PVTS(r, page)->charsets[PSCR(r, page).charset]) { case '0': /* DEC Special Character & Line Drawing Set */ PVTS(r, page)->rstyle |= RS_acsFont; break; case 'A': /* United Kingdom (UK) */ PVTS(r, page)->rstyle |= RS_ukFont; break; case 'B': /* United States (USASCII) */ break; case '<': /* Multinational character set */ break; case '5': /* Finnish character set */ break; case 'C': /* Finnish character set */ break; case 'K': /* German character set */ break; }}/* ------------------------------------------------------------------------- *//* * Choose a font * XTERM_SEQ: Invoke G0 character set: CTRL-O * XTERM_SEQ: Invoke G1 character set: CTRL-N * XTERM_SEQ: Invoke G2 character set: ESC N * XTERM_SEQ: Invoke G3 character set: ESC O *//* EXTPROTO */voidrxvt_scr_charset_choose(rxvt_t* r, int page, int set){ PSCR(r, page).charset = set; rxvt_set_font_style(r, page);}/* ------------------------------------------------------------------------- *//* * Set a font * XTERM_SEQ: Set G0 character set: ESC ( <C> * XTERM_SEQ: Set G1 character set: ESC ) <C> * XTERM_SEQ: Set G2 character set: ESC * <C> * XTERM_SEQ: Set G3 character set: ESC + <C> * See set_font_style for possible values for <C> *//* EXTPROTO */voidrxvt_scr_charset_set(rxvt_t* r, int page, int set, unsigned int ch){#ifdef MULTICHAR_SET PVTS(r, page)->multi_byte = !!(set < 0); set = abs(set);#endif PVTS(r, page)->charsets[set] = (unsigned char)ch; rxvt_set_font_style(r, page);}/* ------------------------------------------------------------------------- * * MAJOR SCREEN MANIPULATION * * ------------------------------------------------------------------------- *//* * Refresh an area */enum{ PART_BEG = 0, PART_END, RC_COUNT};/* EXTPROTO */voidrxvt_scr_expose(rxvt_t* r, int page, int x, int y, int width, int height, Bool refresh){ int i; row_col_t rc[RC_COUNT]; if (PVTS(r, page)->drawn_text == NULL) /* sanity check */ return; x = max(x, (int)r->TermWin.int_bwidth); x = min(x, (int)r->szHint.width); y = max(y, (int)r->TermWin.int_bwidth); y = min(y, (int)r->szHint.height); /* round down */ rc[PART_BEG].col = Pixel2Col(x); rc[PART_BEG].row = Pixel2Row(y); /* round up */ rc[PART_END].col = Pixel2Width(x + width + r->TermWin.fwidth - 1); rc[PART_END].row = Pixel2Row(y + height + r->TermWin.fheight - 1); /* sanity checks */ for (i = PART_BEG; i < RC_COUNT; i++) { MIN_IT(rc[i].col, r->TermWin.ncol - 1); MIN_IT(rc[i].row, r->TermWin.nrow - 1); } DBG_MSG(2,(stderr, "rxvt_scr_expose %d (x:%d, y:%d, w:%d, h:%d) area (c:%d,r:%d)-(c:%d,r:%d)\n", page, x, y, width, height, rc[PART_BEG].col, rc[PART_BEG].row, rc[PART_END].col, rc[PART_END].row)); for (i = rc[PART_BEG].row; i <= rc[PART_END].row; i++) { register int j = rc[PART_BEG].col; register int k = rc[PART_END].col - rc[PART_BEG].col + 1; DBG_MSG(4,(stderr, " memset drawn_text[%d][%d], len=%d\n", i, j, k)); MEMSET(&(PVTS(r, page)->drawn_text[i][j]), 0, k); } if (refresh) { DBG_MSG( 3, ( stderr, "Forcing immediate screen refresh")); rxvt_scr_refresh(r, page, SLOW_REFRESH | REFRESH_BOUNDS); }}/* ------------------------------------------------------------------------- *//* * Refresh the entire screen *//* EXTPROTO */voidrxvt_scr_touch(rxvt_t* r, int page, Bool refresh){ DBG_MSG( 3, (stderr, "rxvt_scr_touch\n")); rxvt_scr_expose(r, page, 0, 0, VT_WIDTH(r), VT_HEIGHT(r), refresh);}/* ------------------------------------------------------------------------- *//* * Move the display so that the line represented by scrollbar value Y is at * the top of the screen *//* EXTPROTO */intrxvt_scr_move_to(rxvt_t* r, int page, int y, int len){ long p = 0; RUINT16T oldviewstart; oldviewstart = VSTART; if (y < len) { p = (r->TermWin.nrow + PVTS(r, page)->nscrolled) * (len - y) / len; p -= (long)(r->TermWin.nrow - 1); p = max(p, 0); } VSTART = (RUINT16T)min(p, PVTS(r, page)->nscrolled); DBG_MSG( 2, (stderr, "rxvt_scr_move_to %d (%d, %d) view_start:%d\n", page, y, len, VSTART)); return rxvt_scr_change_view(r, page, oldviewstart);}/* ------------------------------------------------------------------------- *//* * Page the screen up/down nlines * direction should be UP or DN *//* EXTPROTO */intrxvt_scr_page(rxvt_t* r, int page, enum page_dirn direction, int nlines){ int n; RUINT16T oldviewstart; DBG_MSG( 2, (stderr, "rxvt_scr_page %d (%s, %d) view_start:%d\n", page, ((direction == UP) ? "UP" : "DN"), nlines, VSTART)); assert((nlines >= 0) && (nlines <= r->TermWin.nrow)); oldviewstart = VSTART; if (direction == UP) { n = VSTART + nlines; VSTART = min(n, PVTS(r, page)->nscrolled); } else { n = VSTART - nlines; VSTART = max(n, 0); } return rxvt_scr_change_view(r, page, oldviewstart);}/* INTPROTO */intrxvt_scr_change_view(rxvt_t* r, int page, RUINT16T oldviewstart){ if (VSTART != oldviewstart) { r->h->want_refresh = 1; PVTS(r, page)->num_scr -= (VSTART - oldviewstart); } return (int)(VSTART - oldviewstart);}/* ------------------------------------------------------------------------- *//* EXTPROTO */voidrxvt_scr_bell(rxvt_t *r, int page){#ifndef NO_BELL#if defined(THROTTLE_BELL_MSEC) && THROTTLE_BELL_MSEC > 0 /* Maximal number of bell per pre-defined time interval */ static int bellcount = 0; static struct timeval tvbase = {0, 0}; struct timeval tvnow = {0, 0}; long tminterval; if (gettimeofday (&tvnow, NULL) >= 0) { if (0 == tvbase.tv_sec && 0 == tvbase.tv_usec) { /* first time bell, try avoid integer overflow */ tvbase = tvnow; tminterval = 0; } else tminterval = (tvnow.tv_sec - tvbase.tv_sec) * 1000 + (tvnow.tv_usec - tvbase.tv_usec) / 1000; if (tminterval > THROTTLE_BELL_MSEC) { tvbase = tvnow; bellcount = 1; } else if (bellcount ++ >= THROTTLE_BELL_COUNT) { return; } }#endif /* THROTTLE_BELL_MSEC && THROTTLE_BELL_MSEC > 0 */ if (r->h->rs[Rs_bellCommand]) { /* execute bell command */ system (r->h->rs[Rs_bellCommand]); return ; }# ifndef NO_MAPALERT# ifdef MAPALERT_OPTION if (r->Options & Opt_mapAlert)# endif XMapWindow(r->Xdisplay, r->TermWin.parent);# endif if (r->Options & Opt_visualBell) {#if defined(TRANSPARENT) || defined(BACKGROUND_IMAGE) /* * Reverse video bell doesn't look so good with transparency or a * background pixmap. Flash screen ourselves. */ if (# ifdef TRANSPARENT r->h->am_transparent || r->h->am_pixmap_trans# ifdef BACKGROUND_IMAGE ||# endif# endif# ifdef BACKGROUND_IMAGE None != PVTS(r, page)->pixmap# endif ) { XGCValues values; XGetGCValues( r->Xdisplay, r->TermWin.gc, GCForeground | GCFillStyle, &values); XSetForeground( r->Xdisplay, r->TermWin.gc, r->PixColors[Color_fg] ); XSetFillStyle( r->Xdisplay, r->TermWin.gc, FillSolid); XFillRectangle( r->Xdisplay, PVTS(r, page)->vt, r->TermWin.gc, Row2Pixel(0), Col2Pixel(0), Width2Pixel( r->TermWin.ncol), Height2Pixel( r->TermWin.nrow) ); XChangeGC( r->Xdisplay, r->TermWin.gc, GCForeground | GCFillStyle, &values); XSync( r->Xdisplay, False);# ifdef HAVE_NANOSLEEP struct timespec rqt; rqt.tv_sec = 0; rqt.tv_nsec = 100000000; /* 100 ms */ nanosleep(&rqt, NULL);# else /* * Sleeping for 1 whole second seems just wrong, so we do nothing. */# endif XClearArea( r->Xdisplay, PVTS(r, page)->vt, 0, 0, 0, 0, True); } else#endif /* TRANSPARENT || BACKGROUND_IMAGE */ { /* refresh also done */ rxvt_scr_rvideo_mode(r, page, !PVTS(r, page)->rvideo); rxvt_scr_rvideo_mode(r, page, !PVTS(r, page)->rvideo); } } else XBell(r->Xdisplay, 0);#endif}/* ------------------------------------------------------------------------- */#ifdef PRINTPIPE/* * Generate escape sequences (not including the "\e[0") to reproduce screen * rendition attributes for the foreground / background color. If "fg" is true, * then sequences for the foreground color are generated, otherwise sequences * for setting the background color are generated. * * Returns a pointer to the character after the escape sequence written. If no * further attributes are to be added, strip the trailing ";". *//* INTPROTO */char *escSetColor( char *s, int color, int fg){ if( color >= minCOLOR && color < minCOLOR + 8 ) s += sprintf( s, "%c%d;", fg ? '3' : '4', color - minCOLOR );#ifndef NO_BRIGHTCOLOR else if( color >= minBrightCOLOR && color <= maxBrightCOLOR ) s += sprintf( s, "%s%d;", fg ? "9" : "10", color - minBrightCOLOR );#endif#ifdef TTY_256COLOR else if( color >= min256COLOR && color <= max256COLOR ) s += sprintf( s, "%c8;5;%d;", fg ? '3' : '4', color - min256COLOR + 16 );#endif else assert(0); return s;}#endif/* * Print the screen into the printer pipe. If fullhist != 0, then the entire * scroll back buffer is also dumped. *//* EXTPROTO */voidrxvt_scr_printscreen(rxvt_t* r, int page, int fullhist, int pretty, const char *pipeName ){ DBG_MSG( 1, ( stderr, "rxvt_scr_printscreen( r, %d, %d, %d, %s )\n", page, fullhist, pretty, pipeName ) );#ifdef PRINTPIPE int row, col, nrows, row_offset; text_t *txt; rend_t *rnd; FILE* fd; if ( ( fd = rxvt_popen_printer( r, pipeName ) ) == NULL ) return; nrows = r->TermWin.nrow; row_offset = SVLINES; if (!fullhist) row_offset -= VSTART; else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -