rxvtlib_screen.c

来自「具有IDE功能的编辑器」· C语言 代码 · 共 2,128 行 · 第 1/5 页

C
2,128
字号
#include "rxvtlib.h"/*--------------------------------*-C-*--------------------------------------* * File:	screen.c *---------------------------------------------------------------------------* * $Id: screen.c,v 1.76.2.9 1999/07/07 13:22:22 mason Exp $ * * Copyright (C) 1997,1998 Geoff Wing <gcw@pobox.com> * * 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. *--------------------------------------------------------------------------*//* * We handle _all_ screen updates and selections *//* ------------------------------------------------------------------------- */#ifdef MULTICHAR_SET	/* set ==> currently using 2 bytes per glyph */	/* set ==> we only got half a glyph */#else#endif/* KANJI methods *//* BIG5 methods: CNS not implemented *//* GB method *//* ------------------------------------------------------------------------- *//* ------------------------------------------------------------------------- * *             GENERAL SCREEN AND SELECTION UPDATE ROUTINES                  * * ------------------------------------------------------------------------- *//* these must be row_col_t *//* * 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 *//* ------------------------------------------------------------------------- * *                        SCREEN `COMMON' ROUTINES                           * * ------------------------------------------------------------------------- *//* Fill part/all of a line with blanks. *//* INTPROTO */void            blank_line (text_t * et, rend_t * er, int width, rend_t efs){    MEMSET (et, ' ', width);    for (; width--;)	*er++ = efs;}/* ------------------------------------------------------------------------- *//* Fill a full line with blanks - make sure it is allocated first *//* INTPROTO */void            rxvtlib_blank_screen_mem (rxvtlib *o, text_t ** tp, rend_t ** rp, int row,				  rend_t efs){    int             width = o->TermWin.ncol;    rend_t         *er;    if (tp[row] == NULL) {	tp[row] = MALLOC (sizeof (text_t) * o->TermWin.ncol);	rp[row] = MALLOC (sizeof (rend_t) * o->TermWin.ncol);    }    MEMSET (tp[row], ' ', width);    for (er = rp[row]; width--;)	*er++ = efs;}/* ------------------------------------------------------------------------- * *                          SCREEN INITIALISATION                            * * ------------------------------------------------------------------------- *//* EXTPROTO */void            rxvtlib_scr_reset (rxvtlib *o){    int             i, j, k, total_rows, prev_total_rows;    rend_t          setrstyle;    D_SCREEN ((stderr, "scr_reset()"));    o->TermWin.view_start = 0;    RESET_CHSTAT;    if (o->TermWin.ncol == o->prev_ncol && o->TermWin.nrow == o->prev_nrow)	return;    o->want_refresh = 1;    if (o->TermWin.ncol <= 0)	o->TermWin.ncol = 80;    if (o->TermWin.nrow <= 0)	o->TermWin.nrow = 24;#ifdef DEBUG_STRICT    assert (o->TermWin.saveLines >= 0);#else				/* drive with your eyes closed */    MAX_IT (o->TermWin.saveLines, 0);#endif    total_rows = o->TermWin.nrow + o->TermWin.saveLines;    prev_total_rows = o->prev_nrow + o->TermWin.saveLines;    o->screen.tscroll = 0;    o->screen.bscroll = (o->TermWin.nrow - 1);    if (o->prev_nrow == -1) {/* * A: 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 */	o->screen.text = CALLOC (text_t *, total_rows);	o->buf_text = CALLOC (text_t *, total_rows);	o->drawn_text = CALLOC (text_t *, o->TermWin.nrow);	o->swap.text = CALLOC (text_t *, o->TermWin.nrow);	o->screen.tlen = CALLOC (short, total_rows);	o->buf_tlen = CALLOC (short, total_rows);	o->swap.tlen = CALLOC (short, o->TermWin.nrow);	o->screen.rend = CALLOC (rend_t *, total_rows);	o->buf_rend = CALLOC (rend_t *, total_rows);	o->drawn_rend = CALLOC (rend_t *, o->TermWin.nrow);	o->swap.rend = CALLOC (rend_t *, o->TermWin.nrow);	for (i = 0; i < o->TermWin.nrow; i++) {	    j = i + o->TermWin.saveLines;	    rxvtlib_blank_screen_mem (o, o->screen.text, o->screen.rend, j, DEFAULT_RSTYLE);	    rxvtlib_blank_screen_mem (o, o->swap.text, o->swap.rend, i, DEFAULT_RSTYLE);	    o->screen.tlen[j] = o->swap.tlen[i] = 0;	    rxvtlib_blank_screen_mem (o, o->drawn_text, o->drawn_rend, i, DEFAULT_RSTYLE);	}	o->TermWin.nscrolled = 0;	/* no saved lines */	o->screen.flags = o->swap.flags = Screen_DefaultFlags;	o->save.cur.row = o->save.cur.col = 0;	o->save.charset = 0;	o->save.charset_char = 'B';	o->rstyle = o->save.rstyle = DEFAULT_RSTYLE;	o->selection.text = NULL;	o->selection.len = 0;	o->selection.op = SELECTION_CLEAR;	o->selection.screen = PRIMARY;	o->selection.clicks = 0;	CLEAR_ALL_SELECTION;	MEMSET (o->charsets, 'B', sizeof (o->charsets));	o->current_screen = PRIMARY;	o->rvideo = 0;#ifdef MULTICHAR_SET	o->multi_byte = 0;	o->lost_multi = 0;	o->chstat = SBYTE;# ifdef ZH	o->encoding_method = BIG5;# else#  ifdef ZHCN	o->encoding_method = GB;#  endif# endif#endif    } else {/* * B1: add or delete rows as appropriate */	setrstyle = DEFAULT_RSTYLE | (o->rvideo ? RS_RVid : 0);	if (o->TermWin.nrow < o->prev_nrow) {	    /* delete rows */	    k = min (o->TermWin.nscrolled, o->prev_nrow - o->TermWin.nrow);	    rxvtlib_scroll_text (o, 0, o->prev_nrow - 1, k, 1);	    for (i = o->TermWin.nrow; i < o->prev_nrow; i++) {		j = i + o->TermWin.saveLines;		if (o->screen.text[j])		    FREE (o->screen.text[j]);		if (o->screen.rend[j])		    FREE (o->screen.rend[j]);		if (o->swap.text[i])		    FREE (o->swap.text[i]);		if (o->swap.rend[i])		    FREE (o->swap.rend[i]);		FREE (o->drawn_text[i]);		FREE (o->drawn_rend[i]);	    }	    /* we have fewer rows so fix up cursor position */	    MIN_IT (o->screen.cur.row, o->TermWin.nrow - 1);	    MIN_IT (o->swap.cur.row, o->TermWin.nrow - 1);	    rxvtlib_scr_reset_realloc (o);	/* REALLOC _last_ */	} else if (o->TermWin.nrow > o->prev_nrow) {	    /* add rows */	    rxvtlib_scr_reset_realloc (o);	/* REALLOC _first_ */	    k = min (o->TermWin.nscrolled, o->TermWin.nrow - o->prev_nrow);	    for (i = prev_total_rows; i < total_rows - k; i++) {		o->screen.tlen[i] = 0;		o->screen.text[i] = NULL;		rxvtlib_blank_screen_mem (o, o->screen.text, o->screen.rend, i, setrstyle);	    }	    for (i = total_rows - k; i < total_rows; i++) {		o->screen.tlen[i] = 0;		o->screen.text[i] = NULL;		o->screen.rend[i] = NULL;	    }	    for (i = o->prev_nrow; i < o->TermWin.nrow; i++) {		o->swap.tlen[i] = 0;		o->swap.text[i] = NULL;		o->drawn_text[i] = NULL;		rxvtlib_blank_screen_mem (o, o->swap.text, o->swap.rend, i, setrstyle);		rxvtlib_blank_screen_mem (o, o->drawn_text, o->drawn_rend, i, setrstyle);	    }	    if (k > 0) {		rxvtlib_scroll_text (o, 0, o->TermWin.nrow - 1, -k, 1);		o->screen.cur.row += k;		o->TermWin.nscrolled -= k;		for (i = o->TermWin.saveLines - o->TermWin.nscrolled; k--; i--)		    if (o->screen.text[i] == NULL) {			rxvtlib_blank_screen_mem (o, o->screen.text, o->screen.rend, i,					  setrstyle);			o->screen.tlen[i] = 0;		    }	    }#ifdef DEBUG_STRICT	    assert (o->screen.cur.row < o->TermWin.nrow);	    assert (o->swap.cur.row < o->TermWin.nrow);#else				/* drive with your eyes closed */	    MIN_IT (o->screen.cur.row, o->TermWin.nrow - 1);	    MIN_IT (o->swap.cur.row, o->TermWin.nrow - 1);#endif	}/* B2: resize columns */	if (o->TermWin.ncol != o->prev_ncol) {	    for (i = 0; i < total_rows; i++) {		if (o->screen.text[i]) {		    o->screen.text[i] = REALLOC (o->screen.text[i],					      o->TermWin.ncol * sizeof (text_t));		    o->screen.rend[i] = REALLOC (o->screen.rend[i],					      o->TermWin.ncol * sizeof (rend_t));		    MIN_IT (o->screen.tlen[i], o->TermWin.ncol);		    if (o->TermWin.ncol > o->prev_ncol)			blank_line (&(o->screen.text[i][o->prev_ncol]),				    &(o->screen.rend[i][o->prev_ncol]),				    o->TermWin.ncol - o->prev_ncol, setrstyle);		}	    }	    for (i = 0; i < o->TermWin.nrow; i++) {		o->drawn_text[i] = REALLOC (o->drawn_text[i],					 o->TermWin.ncol * sizeof (text_t));		o->drawn_rend[i] = REALLOC (o->drawn_rend[i],					 o->TermWin.ncol * sizeof (rend_t));		if (o->swap.text[i]) {		    o->swap.text[i] = REALLOC (o->swap.text[i],					    o->TermWin.ncol * sizeof (text_t));		    o->swap.rend[i] = REALLOC (o->swap.rend[i],					    o->TermWin.ncol * sizeof (rend_t));		    MIN_IT (o->swap.tlen[i], o->TermWin.ncol);		    if (o->TermWin.ncol > o->prev_ncol)			blank_line (&(o->swap.text[i][o->prev_ncol]),				    &(o->swap.rend[i][o->prev_ncol]),				    o->TermWin.ncol - o->prev_ncol, setrstyle);		}		if (o->TermWin.ncol > o->prev_ncol)		    blank_line (&(o->drawn_text[i][o->prev_ncol]),				&(o->drawn_rend[i][o->prev_ncol]),				o->TermWin.ncol - o->prev_ncol, setrstyle);	    }	    MIN_IT (o->screen.cur.col, o->TermWin.ncol - 1);	    MIN_IT (o->swap.cur.col, o->TermWin.ncol - 1);	}	if (o->tabs)	    FREE (o->tabs);    }    o->tabs = MALLOC (o->TermWin.ncol * sizeof (char));    for (i = 0; i < o->TermWin.ncol; i++)	o->tabs[i] = (i % TABSIZE == 0) ? 1 : 0;    o->prev_nrow = o->TermWin.nrow;    o->prev_ncol = o->TermWin.ncol;    rxvtlib_tt_resize (o);}/* INTPROTO */void            rxvtlib_scr_reset_realloc (rxvtlib *o){    int             total_rows;    total_rows = o->TermWin.nrow + o->TermWin.saveLines;/* *INDENT-OFF* */    o->screen.text = REALLOC(o->screen.text, total_rows   * sizeof(text_t *));    o->buf_text    = REALLOC(o->buf_text   , total_rows   * sizeof(text_t *));    o->drawn_text  = REALLOC(o->drawn_text , o->TermWin.nrow * sizeof(text_t *));    o->swap.text   = REALLOC(o->swap.text  , o->TermWin.nrow * sizeof(text_t *));    o->screen.tlen = REALLOC(o->screen.tlen, total_rows   * sizeof(short));    o->buf_tlen    = REALLOC(o->buf_tlen   , total_rows   * sizeof(short));    o->swap.tlen   = REALLOC(o->swap.tlen  , total_rows   * sizeof(short));    o->screen.rend = REALLOC(o->screen.rend, total_rows   * sizeof(rend_t *));    o->buf_rend    = REALLOC(o->buf_rend   , total_rows   * sizeof(rend_t *));    o->drawn_rend  = REALLOC(o->drawn_rend , o->TermWin.nrow * sizeof(rend_t *));    o->swap.rend   = REALLOC(o->swap.rend  , o->TermWin.nrow * sizeof(rend_t *));/* *INDENT-ON* */}/* ------------------------------------------------------------------------- *//* * Free everything.  That way malloc debugging can find leakage. *//* EXTPROTO */void            rxvtlib_scr_release (rxvtlib *o){    int             i, total_rows;    total_rows = o->TermWin.nrow + o->TermWin.saveLines;    for (i = 0; i < total_rows; i++) {	if (o->screen.text[i]) {	/* then so is screen.rend[i] */	    FREE (o->screen.text[i]);	    FREE (o->screen.rend[i]);	}    }    for (i = 0; i < o->TermWin.nrow; i++) {	FREE (o->drawn_text[i]);	FREE (o->drawn_rend[i]);	FREE (o->swap.text[i]);	FREE (o->swap.rend[i]);    }    FREE (o->screen.text);    FREE (o->screen.tlen);    FREE (o->screen.rend);    FREE (o->drawn_text);    FREE (o->drawn_rend);    FREE (o->swap.text);    FREE (o->swap.tlen);    FREE (o->swap.rend);    FREE (o->buf_text);    FREE (o->buf_tlen);    FREE (o->buf_rend);    FREE (o->tabs);/* NULL these so if anything tries to use them, we'll know about it */    o->screen.text = o->drawn_text = o->swap.text = NULL;    o->screen.rend = o->drawn_rend = o->swap.rend = NULL;    o->screen.tlen = o->swap.tlen = o->buf_tlen = NULL;    o->buf_text = NULL;    o->buf_rend = NULL;    o->tabs = NULL;}/* ------------------------------------------------------------------------- *//* EXTPROTO */void            rxvtlib_scr_poweron (rxvtlib *o){    D_SCREEN ((stderr, "scr_poweron()"));    MEMSET (o->charsets, 'B', sizeof (o->charsets));    o->rvideo = 0;    o->swap.tscroll = 0;    o->swap.bscroll = o->TermWin.nrow - 1;    o->screen.cur.row = o->screen.cur.col = o->swap.cur.row = o->swap.cur.col = 0;    o->screen.charset = o->swap.charset = 0;    o->screen.flags = o->swap.flags = Screen_DefaultFlags;    rxvtlib_scr_cursor (o, SAVE);    rxvtlib_scr_release (o);    o->prev_nrow = -1;    o->prev_ncol = -1;    rxvtlib_scr_reset (o);    rxvtlib_scr_clear (o);    rxvtlib_scr_refresh (o, SLOW_REFRESH);    rxvtlib_Gr_reset (o);}/* ------------------------------------------------------------------------- * *                         PROCESS SCREEN COMMANDS                           * * ------------------------------------------------------------------------- *//* * Save and Restore cursor * XTERM_SEQ: Save cursor   : ESC 7      * XTERM_SEQ: Restore cursor: ESC 8 *//* EXTPROTO */void            rxvtlib_scr_cursor (rxvtlib *o, int mode){    D_SCREEN ((stderr, "scr_cursor(%c)", mode));    switch (mode) {    case SAVE:	o->save.cur.row = o->screen.cur.row;	o->save.cur.col = o->screen.cur.col;	o->save.rstyle = o->rstyle;	o->save.charset = o->screen.charset;	o->save.charset_char = o->charsets[o->screen.charset];	break;    case RESTORE:	o->want_refresh = 1;	o->screen.cur.row = o->save.cur.row;	o->screen.cur.col = o->save.cur.col;	o->rstyle = o->save.rstyle;	o->screen.charset = o->save.charset;	o->charsets[o->screen.charset] = o->save.charset_char;	rxvtlib_set_font_style (o);	break;    }/* boundary check in case screen size changed between SAVE and RESTORE */    MIN_IT (o->screen.cur.row, o->TermWin.nrow - 1);    MIN_IT (o->screen.cur.col, o->TermWin.ncol - 1);#ifdef DEBUG_STRICT    assert (o->screen.cur.row >= 0);    assert (o->screen.cur.col >= 0);

⌨️ 快捷键说明

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