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 + -
显示快捷键?