⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 screen.c

📁 multi-tabed terminal based on rxvt
💻 C
📖 第 1 页 / 共 5 页
字号:
/*--------------------------------*-C-*---------------------------------* * File:    screen.c *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. * Copyright (c) 1997-2001   Geoff Wing <gcw@pobox.com> * Copyright (C) 2000,2001   Teepanis Chachiyo <teepanis@physics.purdue.edu> * Copyright (c) 2001        Marius Gedminas <marius.gedminas@uosis.mif.vu.lt> * Copyright (c) 2003        David Hull * Copyright (c) 2003        Yamanobe Kiichiro <yamky@cocoa.freemail.ne.jp> * Copyright (c) 2003        Mamoru Komachi <usata@usata.org> * Copyright (c) 2005        William P. Y. Hadisoeseno <williampoetra@users.sourceforge.net> * Copyright (c) 2004-2006   Jingmin Zhou <jimmyzhou@users.sourceforge.net> * Copyright (c) 2005-2006   Gautam Iyer <gi1242@users.sourceforge.net> * Copyright (c) 2007		  Jehan Hysseo <hysseo@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *----------------------------------------------------------------------*/#include "../config.h"#define INTERN_SCREEN#include "rxvt.h"#ifdef XFT_SUPPORT# include <xftacs.h>#endif#ifdef HAVE_WORDEXP_H# include <wordexp.h>#endif/* ------------------------------------------------------------------------- */#ifdef MULTICHAR_SET#define RESET_CHSTAT(R, P)		    \    if (PVTS((R),(P))->chstat == WBYTE)	\	PVTS((R),(P))->chstat = SBYTE, PVTS((R),(P))->lost_multi = 1#else# define RESET_CHSTAT(R, P)#endif/* ------------------------------------------------------------------------- */#define PROP_SIZE	16384/* ------------------------------------------------------------------------- * *	     GENERAL SCREEN AND SELECTION UPDATE ROUTINES		  * * ------------------------------------------------------------------------- *//*** If inhibit scrolling on tty output, we should keep the view_start.** Otherwise, we set it to zero.*/#define ZERO_SCROLLBACK(R, P)			    \    if (NOTSET_OPTION(R, Opt_scrollTtyOutputInhibit))	\	(R)->vts[(P)]->view_start = 0#define CLEAR_SELECTION(R)			\    (R)->selection.beg.row = \    (R)->selection.beg.col = \    (R)->selection.end.row = \    (R)->selection.end.col = 0#define CLEAR_ALL_SELECTION(R)			\    (R)->selection.beg.row = \    (R)->selection.beg.col = \    (R)->selection.mark.row = \    (R)->selection.mark.col = \    (R)->selection.end.row = \    (R)->selection.end.col = 0#define ROW_AND_COL_IS_AFTER(A, B, C, D)		\    (((A) > (C)) || (((A) == (C)) && ((B) > (D))))#define ROW_AND_COL_IS_BEFORE(A, B, C, D)		\    (((A) < (C)) || (((A) == (C)) && ((B) < (D))))#define ROW_AND_COL_IN_ROW_AFTER(A, B, C, D)		\    (((A) == (C)) && ((B) > (D)))#define ROW_AND_COL_IN_ROW_AT_OR_AFTER(A, B, C, D)	\    (((A) == (C)) && ((B) >= (D)))#define ROW_AND_COL_IN_ROW_BEFORE(A, B, C, D)		\    (((A) == (C)) && ((B) < (D)))#define ROW_AND_COL_IN_ROW_AT_OR_BEFORE(A, B, C, D)	\    (((A) == (C)) && ((B) <= (D)))/* these must be row_col_t */#define RC_AFTER(X, Y)			    \    ROW_AND_COL_IS_AFTER((X).row, (X).col, (Y).row, (Y).col)#define RC_BEFORE(X, Y)			    \    ROW_AND_COL_IS_BEFORE((X).row, (X).col, (Y).row, (Y).col)#define RC_ROW_AFTER(X, Y)		    \    ROW_AND_COL_IN_ROW_AFTER((X).row, (X).col, (Y).row, (Y).col)#define RC_ROW_BEFORE(X, Y)		    \    ROW_AND_COL_IN_ROW_BEFORE((X).row, (X).col, (Y).row, (Y).col)#define RC_ROW_ATAFTER(X, Y)			\    ROW_AND_COL_IN_ROW_AT_OR_AFTER((X).row, (X).col, (Y).row, (Y).col)#define RC_ROW_ATBEFORE(X, Y)		    \    ROW_AND_COL_IN_ROW_AT_OR_BEFORE((X).row, (X).col, (Y).row, (Y).col)/* * CLEAR_ROWS : clear <num> rows starting from row <row> * CLEAR_CHARS: clear <num> chars starting from pixel position <x,y> * ERASE_ROWS : set <num> rows starting from row <row> to the foreground colour */#define drawBuffer  (PVTS(r, page)->vt)#define CLEAR_ROWS(row, num)				\    if (r->TermWin.mapped)				\	rxvt_clear_area (r, page,			\	    r->TermWin.int_bwidth, Row2Pixel(row),	\	    VT_WIDTH(r), (unsigned int)Height2Pixel(num))/* * If already_cleared, then we got here during a clipped refresh. In this case, * areas we draw into are already cleared by the server. We don't need to clear * it ourself. (Doing so will cause problems under transparency: E.g. We want to * clear an entire character cell, but an expose event was generated for only * half the character cell. By our wonderful clippings, we redraw only half the * char cell. However requests to this function will clear an ENTIRE char cell, * causing problems. * * If garbage is found due to clipped refreshes, then we should explicitly call * XClearArea before generating a clipped refresh. */#define CLEAR_CHARS(r, page, already_cleared, x, y, num)	\	if( !already_cleared )					\	    rxvt_clear_area( (r), (page), (x), (y),		\		(unsigned) Width2Pixel((num)),			\		(unsigned) Height2Pixel(1));#define ERASE_ROWS(row, num)			    \    rxvt_fill_rectangle (r, page,		    \	   r->TermWin.int_bwidth, Row2Pixel(row),   \	   VT_WIDTH(r),	(unsigned int)Height2Pixel(num))#ifdef DONT_SELECT_TRAILING_SPACES# define STRIP_TRAILING_SPACE(str, fence)	    \    while (str > fence && ' ' == str[-1])	    \	str --;#endif/* Here are some simple macros for convenience */#undef CURROW#undef CURCOL#undef SVLINES#undef VSTART#define CURROW	    (PSCR(r, page).cur.row)#define CURCOL	    (PSCR(r, page).cur.col)#define SVLINES	    (PVTS(r, page)->saveLines)#define VSTART	    (PVTS(r, page)->view_start)/*--------------------------------------------------------------------* *         BEGIN `INTERNAL' ROUTINE PROTOTYPES                        * *--------------------------------------------------------------------*/void rxvt_blank_line              (text_t*, rend_t*, unsigned int, rend_t);void rxvt_blank_screen_mem        (rxvt_t*, int, text_t**, rend_t **, unsigned int, rend_t);void rxvt_scr_reset_realloc       (rxvt_t*, int);void rxvt_scr_delete_row          (rxvt_t*, int);void rxvt_scr_add_row             (rxvt_t*, int, unsigned int, unsigned int);void static inline rxvt_clear_area       (rxvt_t*, int page, int x, int y, unsigned int w, unsigned int h);void static inline rxvt_fill_rectangle   (rxvt_t*, int page, int x, int y, unsigned int w, unsigned int h);voidrxvt_scr_draw_string (rxvt_t* r, int page,	int x, int y, char* str, int len, int drawfunc,	uint16_t fore, uint16_t back,	__attribute__((unused)) rend_t rend, Region refreshRegion);void rxvt_scr_adjust_col          (rxvt_t*, int, unsigned int);void rxvt_set_font_style          (rxvt_t*, int);int  rxvt_scr_change_view         (rxvt_t*, int, uint16_t);void rxvt_scr_reverse_selection   (rxvt_t*, int);void rxvt_paste_str                 (rxvt_t*, int, const unsigned char*, unsigned int);int  rxvt_selection_request_other (rxvt_t*, int, Atom, int);void rxvt_selection_start_colrow  (rxvt_t*, int, int, int);void rxvt_selection_delimit_word  (rxvt_t*, int, enum page_dirn, const row_col_t*, row_col_t*);#ifdef MULTICHAR_SETvoid rxvt_selection_adjust_kanji  (rxvt_t*, int);#endifvoid rxvt_selection_extend_colrow (rxvt_t*, int, int32_t, int32_t, int, int, int);#ifndef NO_FRILLSvoid rxvt_selection_trim          (rxvt_t*, int);#endif#ifdef TEXT_SHADOW# ifdef XFT_SUPPORTvoid rxvt_set_clipping		  (rxvt_t*, XftDraw*, GC, Region, int, int, unsigned, unsigned, int*, int*);void rxvt_free_clipping		  (rxvt_t*, XftDraw*, GC, Region);# elsevoid rxvt_set_clipping		  (rxvt_t*, __attribute__((unused)) void*, GC, Region, int, int, unsigned, unsigned, int*, int*);void rxvt_free_clipping		  (rxvt_t*, __attribute__((unused)) void*, GC, Region);# endif#endif#ifdef XFT_SUPPORT#endif	/* XFT_SUPPORT *//*--------------------------------------------------------------------* *         END   `INTERNAL' ROUTINE PROTOTYPES                        * *--------------------------------------------------------------------*/ /* ------------------------------------------------------------------------- * *			SCREEN `COMMON' ROUTINES			   * * ------------------------------------------------------------------------- *//* Fill part/all of a line with blanks. *//* INTPROTO */voidrxvt_blank_line(text_t *et, rend_t *er, unsigned int width, rend_t efs){    MEMSET(et, ' ', (size_t)width);    efs &= ~RS_baseattrMask;    for (; width--;)	*er++ = efs;}/* ------------------------------------------------------------------------- *//* Fill a full line with blanks - make sure it is allocated first *//* INTPROTO */voidrxvt_blank_screen_mem(rxvt_t* r, int page, text_t **tp, rend_t **rp,	unsigned int row, rend_t efs){    int		 width = r->TermWin.ncol;    rend_t	 *er;    assert ((tp[row] && rp[row]) ||	(tp[row] == NULL && rp[row] == NULL));    /* possible integer overflow? */    assert (width > 0);    assert (sizeof (text_t) * width > 0);    assert (sizeof (rend_t) * width > 0);    if (tp[row] == NULL)    {	tp[row] = rxvt_malloc(sizeof(text_t) * width);	rp[row] = rxvt_malloc(sizeof(rend_t) * width);    }    MEMSET(tp[row], ' ', width);    efs &= ~RS_baseattrMask;    for (er = rp[row]; width--;)	*er++ = efs;}/* ------------------------------------------------------------------------- * *			  SCREEN INITIALISATION				* * ------------------------------------------------------------------------- *//* EXTPROTO */voidrxvt_init_screen (rxvt_t* r){    int	    p;    int	    ncol = r->TermWin.ncol;    /* first time, we don't have r->tabstop yet */    rxvt_dbgmsg ((DBG_VERBOSE, DBG_SCREEN, "allocate r->tabstop as %d\n", ncol));    assert (ncol > 0);	/* possible integer overflow? */    r->tabstop = rxvt_malloc(ncol * sizeof(char));    for (p = 0; p < ncol; p++)	r->tabstop[p] = (p % TABSTOP_SIZE == 0) ? 1 : 0;}voidrxvt_scr_alloc (rxvt_t* r, int page){    unsigned int    ncol, nrow, total_rows;    unsigned int    p, q;    rxvt_dbgmsg ((DBG_VERBOSE, DBG_SCREEN, "rxvt_scr_alloc %d ()\n", page));    ncol = r->TermWin.ncol;    nrow = r->TermWin.nrow;    total_rows = nrow + SVLINES;    /*    ** First time called so just malloc everything : don't rely on    ** realloc    ** Note: this is still needed so that all the scrollback lines    ** are NULL    */    PVTS(r, page)->buf_text = rxvt_calloc(total_rows, sizeof(text_t*));    PVTS(r, page)->buf_rend = rxvt_calloc(total_rows, sizeof(rend_t*));    PVTS(r, page)->drawn_text = rxvt_calloc(nrow, sizeof(text_t*));    PVTS(r, page)->drawn_rend = rxvt_calloc(nrow, sizeof(rend_t*));    PSCR(r, page).text = rxvt_calloc(total_rows, sizeof(text_t*));    PSCR(r, page).tlen = rxvt_calloc(total_rows, sizeof(int16_t));    PSCR(r, page).rend = rxvt_calloc(total_rows, sizeof(rend_t*));#if NSCREENS    PVTS(r, page)->swap.text = rxvt_calloc(nrow, sizeof(text_t*));    PVTS(r, page)->swap.tlen = rxvt_calloc(nrow, sizeof(int16_t));    PVTS(r, page)->swap.rend = rxvt_calloc(nrow, sizeof(rend_t*));#endif    for (p = 0; p < nrow; p++)    {	q = p + SVLINES;	rxvt_blank_screen_mem (r, page, PSCR(r, page).text,	    PSCR(r, page).rend, q, DEFAULT_RSTYLE);	PSCR(r, page).tlen[q] = 0;#if NSCREENS	rxvt_blank_screen_mem (r, page, PVTS(r, page)->swap.text,	    PVTS(r, page)->swap.rend, p, DEFAULT_RSTYLE);	PVTS(r, page)->swap.tlen[p] = 0;#endif	rxvt_blank_screen_mem (r, page, PVTS(r, page)->drawn_text,	    PVTS(r, page)->drawn_rend, p, DEFAULT_RSTYLE);    }    PVTS(r, page)->nscrolled = 0;   /* no saved lines */    PSCR(r, page).flags = Screen_DefaultFlags;    PSCR(r, page).cur.row = 0;    PSCR(r, page).cur.col = 0;    PSCR(r, page).charset = 0;    PVTS(r, page)->current_screen = PRIMARY;    rxvt_scr_cursor(r, page, SAVE);#if NSCREENS    PVTS(r, page)->swap.flags = Screen_DefaultFlags;    PVTS(r, page)->swap.cur.row = 0;    PVTS(r, page)->swap.cur.col = 0;    PVTS(r, page)->swap.charset = 0;    PVTS(r, page)->current_screen = SECONDARY;    rxvt_scr_cursor(r, page, SAVE);    PVTS(r, page)->current_screen = PRIMARY;#endif    PVTS(r, page)->rstyle = DEFAULT_RSTYLE;    PVTS(r, page)->rvideo = 0;    MEMSET(&(PVTS(r, page)->charsets), 'B', sizeof(PVTS(r, page)->charsets));#ifdef MULTICHAR_SET    PVTS(r, page)->multi_byte = 0;    PVTS(r, page)->lost_multi = 0;    PVTS(r, page)->chstat = SBYTE;#endif    /* Now set screen initialization flag */    PVTS(r, page)->init_screen = 1;}/* INTPROTO */voidrxvt_scr_reset_realloc(rxvt_t* r, int page){    unsigned int   total_rows, nrow;    rxvt_dbgmsg ((DBG_VERBOSE, DBG_SCREEN, "rxvt_scr_reset_realloc %d ()\n", page));    nrow = r->TermWin.nrow;    total_rows = nrow + SVLINES;    PSCR(r, page).text = rxvt_realloc (	PSCR(r, page).text, total_rows * sizeof(text_t *));    PSCR(r, page).tlen = rxvt_realloc (	PSCR(r, page).tlen, total_rows * sizeof(int16_t));    PSCR(r, page).rend = rxvt_realloc (	PSCR(r, page).rend, total_rows * sizeof(rend_t *));#if NSCREENS    PVTS(r, page)->swap.text   = rxvt_realloc (	PVTS(r, page)->swap.text, nrow * sizeof(text_t *));    PVTS(r, page)->swap.tlen   = rxvt_realloc (	PVTS(r, page)->swap.tlen  , total_rows * sizeof(int16_t));    PVTS(r, page)->swap.rend   = rxvt_realloc (	PVTS(r, page)->swap.rend, nrow * sizeof(rend_t *));#endif    PVTS(r, page)->buf_text = rxvt_realloc (	PVTS(r, page)->buf_text, total_rows * sizeof(text_t *));    PVTS(r, page)->buf_rend = rxvt_realloc (	PVTS(r, page)->buf_rend, total_rows * sizeof(rend_t *));    PVTS(r, page)->drawn_text  = rxvt_realloc (	PVTS(r, page)->drawn_text, nrow * sizeof(text_t *));    PVTS(r, page)->drawn_rend  = rxvt_realloc (	PVTS(r, page)->drawn_rend, nrow * sizeof(rend_t *));}/* INTPROTO */voidrxvt_scr_delete_row (rxvt_t* r, int page){    unsigned int    nrow, prev_nrow;    unsigned int    p, q;    register int    i;    rxvt_dbgmsg ((DBG_VERBOSE, DBG_SCREEN, "rxvt_scr_delete_row %d ()\n", page));    nrow = r->TermWin.nrow;    prev_nrow = PVTS(r, page)->prev_nrow;    /* delete rows */    i = min(PVTS(r, page)->nscrolled, prev_nrow - nrow);    rxvt_scroll_text(r, page, 0, (int)prev_nrow - 1, i, 1);    for (p = nrow; p < prev_nrow; p++)    {	q = p + SVLINES;	if (PSCR(r, page).text[q])	{	    assert(PSCR(r, page).rend[q]);	    rxvt_free(PSCR(r, page).text[q]);	    PSCR(r, page).text[q] = NULL;	    rxvt_free(PSCR(r, page).rend[q]);	    PSCR(r, page).rend[q] = NULL;	}#if NSCREENS	if (PVTS(r, page)->swap.text[p])	{	    assert(PVTS(r, page)->swap.rend[p]);	    rxvt_free(PVTS(r, page)->swap.text[p]);	    PVTS(r, page)->swap.text[p] = NULL;	    rxvt_free(PVTS(r, page)->swap.rend[p]);	    PVTS(r, page)->swap.rend[p] = NULL;	}#endif	assert (PVTS(r, page)->drawn_text[p]);	assert (PVTS(r, page)->drawn_rend[p]);	rxvt_free(PVTS(r, page)->drawn_text[p]);	PVTS(r, page)->drawn_text[p] = NULL;	rxvt_free(PVTS(r, page)->drawn_rend[p]);	PVTS(r, page)->drawn_rend[p] = NULL;    }    /* we have fewer rows so fix up cursor position */    MIN_IT(PSCR(r, page).cur.row, (int32_t)nrow - 1);#if NSCREENS    MIN_IT(PVTS(r, page)->swap.cur.row, (int32_t)nrow - 1);#endif    rxvt_scr_reset_realloc (r, page);	/* realloc _last_ */}/* INTPROTO */voidrxvt_scr_add_row (rxvt_t* r, int page, unsigned int total_rows, unsigned int prev_total_rows){    unsigned int    nrow, prev_nrow;    unsigned int    p;    register int    i;    rxvt_dbgmsg ((DBG_DEBUG, DBG_SCREEN, "%s( page=%d, total_rows=%u, prev_total_rows=%u )\n", __func__, page, total_rows, prev_total_rows ));    nrow = r->TermWin.nrow;    prev_nrow = PVTS(r, page)->prev_nrow;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -