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

📄 terminal.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    sfree(cline);	    line->temporary = FALSE;   /* reconstituted line is now real */	    term->tempsblines -= 1;	    addpos234(term->screen, line, 0);	    term->curs.y += 1;	    term->savecurs.y += 1;	} else {	    /* Add a new blank line at the bottom of the screen. */	    line = newline(term, newcols, FALSE);	    addpos234(term->screen, line, count234(term->screen));	}	term->rows += 1;    }    /* Do this loop to shrink the screen if newrows < rows */    while (term->rows > newrows) {	if (term->curs.y < term->rows - 1) {	    /* delete bottom row, unless it contains the cursor */	    sfree(delpos234(term->screen, term->rows - 1));	} else {	    /* push top row to scrollback */	    line = delpos234(term->screen, 0);	    addpos234(term->scrollback, compressline(line), sblen++);	    freeline(line);	    term->tempsblines += 1;	    term->curs.y -= 1;	    term->savecurs.y -= 1;	}	term->rows -= 1;    }    assert(term->rows == newrows);    assert(count234(term->screen) == newrows);    /* Delete any excess lines from the scrollback. */    while (sblen > newsavelines) {	line = delpos234(term->scrollback, 0);	sfree(line);	sblen--;    }    if (sblen < term->tempsblines)	term->tempsblines = sblen;    assert(count234(term->scrollback) <= newsavelines);    assert(count234(term->scrollback) >= term->tempsblines);    term->disptop = 0;    /* Make a new displayed text buffer. */    newdisp = snewn(newrows, termline *);    for (i = 0; i < newrows; i++) {	newdisp[i] = newline(term, newcols, FALSE);	for (j = 0; j < newcols; j++)	    newdisp[i]->chars[i].attr = ATTR_INVALID;    }    if (term->disptext) {	for (i = 0; i < oldrows; i++)	    freeline(term->disptext[i]);    }    sfree(term->disptext);    term->disptext = newdisp;    term->dispcursx = term->dispcursy = -1;    /* Make a new alternate screen. */    newalt = newtree234(NULL);    for (i = 0; i < newrows; i++) {	line = newline(term, newcols, TRUE);	addpos234(newalt, line, i);    }    if (term->alt_screen) {	while (NULL != (line = delpos234(term->alt_screen, 0)))	    freeline(line);	freetree234(term->alt_screen);    }    term->alt_screen = newalt;    term->alt_sblines = 0;    term->tabs = sresize(term->tabs, newcols, unsigned char);    {	int i;	for (i = (term->cols > 0 ? term->cols : 0); i < newcols; i++)	    term->tabs[i] = (i % 8 == 0 ? TRUE : FALSE);    }    /* Check that the cursor positions are still valid. */    if (term->savecurs.y < 0)	term->savecurs.y = 0;    if (term->savecurs.y >= newrows)	term->savecurs.y = newrows - 1;    if (term->curs.y < 0)	term->curs.y = 0;    if (term->curs.y >= newrows)	term->curs.y = newrows - 1;    if (term->curs.x >= newcols)	term->curs.x = newcols - 1;    term->alt_x = term->alt_y = 0;    term->wrapnext = term->alt_wnext = FALSE;    term->rows = newrows;    term->cols = newcols;    term->savelines = newsavelines;    swap_screen(term, save_alt_which, FALSE, FALSE);    update_sbar(term);    term_update(term);    if (term->resize_fn)	term->resize_fn(term->resize_ctx, term->cols, term->rows);}/* * Hand a function and context pointer to the terminal which it can * use to notify a back end of resizes. */void term_provide_resize_fn(Terminal *term,			    void (*resize_fn)(void *, int, int),			    void *resize_ctx){    term->resize_fn = resize_fn;    term->resize_ctx = resize_ctx;    if (term->cols > 0 && term->rows > 0)	resize_fn(resize_ctx, term->cols, term->rows);}/* Find the bottom line on the screen that has any content. * If only the top line has content, returns 0. * If no lines have content, return -1. */ static int find_last_nonempty_line(Terminal * term, tree234 * screen){    int i;    for (i = count234(screen) - 1; i >= 0; i--) {	termline *line = index234(screen, i);	int j;	for (j = 0; j < line->cols; j++)	    if (!termchars_equal(&line->chars[j], &term->erase_char))		break;	if (j != line->cols) break;    }    return i;}/* * Swap screens. If `reset' is TRUE and we have been asked to * switch to the alternate screen, we must bring most of its * configuration from the main screen and erase the contents of the * alternate screen completely. (This is even true if we're already * on it! Blame xterm.) */static void swap_screen(Terminal *term, int which, int reset, int keep_cur_pos){    int t;    tree234 *ttr;    if (!which)	reset = FALSE;		       /* do no weird resetting if which==0 */    if (which != term->alt_which) {	term->alt_which = which;	ttr = term->alt_screen;	term->alt_screen = term->screen;	term->screen = ttr;	term->alt_sblines = find_last_nonempty_line(term, term->alt_screen) + 1;	t = term->curs.x;	if (!reset && !keep_cur_pos)	    term->curs.x = term->alt_x;	term->alt_x = t;	t = term->curs.y;	if (!reset && !keep_cur_pos)	    term->curs.y = term->alt_y;	term->alt_y = t;	t = term->marg_t;	if (!reset) term->marg_t = term->alt_t;	term->alt_t = t;	t = term->marg_b;	if (!reset) term->marg_b = term->alt_b;	term->alt_b = t;	t = term->dec_om;	if (!reset) term->dec_om = term->alt_om;	term->alt_om = t;	t = term->wrap;	if (!reset) term->wrap = term->alt_wrap;	term->alt_wrap = t;	t = term->wrapnext;	if (!reset) term->wrapnext = term->alt_wnext;	term->alt_wnext = t;	t = term->insert;	if (!reset) term->insert = term->alt_ins;	term->alt_ins = t;	t = term->cset;	if (!reset) term->cset = term->alt_cset;	term->alt_cset = t;	t = term->utf;	if (!reset) term->utf = term->alt_utf;	term->alt_utf = t;	t = term->sco_acs;	if (!reset) term->sco_acs = term->alt_sco_acs;	term->alt_sco_acs = t;    }    if (reset && term->screen) {	/*	 * Yes, this _is_ supposed to honour background-colour-erase.	 */	erase_lots(term, FALSE, TRUE, TRUE);    }}/* * Update the scroll bar. */static void update_sbar(Terminal *term){    int nscroll = sblines(term);    set_sbar(term->frontend, nscroll + term->rows,	     nscroll + term->disptop, term->rows);}/* * Check whether the region bounded by the two pointers intersects * the scroll region, and de-select the on-screen selection if so. */static void check_selection(Terminal *term, pos from, pos to){    if (poslt(from, term->selend) && poslt(term->selstart, to))	deselect(term);}/* * Scroll the screen. (`lines' is +ve for scrolling forward, -ve * for backward.) `sb' is TRUE if the scrolling is permitted to * affect the scrollback buffer. */static void scroll(Terminal *term, int topline, int botline, int lines, int sb){    termline *line;    int i, seltop, olddisptop, shift;    if (topline != 0 || term->alt_which != 0)	sb = FALSE;    olddisptop = term->disptop;    shift = lines;    if (lines < 0) {	while (lines < 0) {	    line = delpos234(term->screen, botline);            resizeline(term, line, term->cols);	    for (i = 0; i < term->cols; i++)		copy_termchar(line, i, &term->erase_char);	    line->lattr = LATTR_NORM;	    addpos234(term->screen, line, topline);	    if (term->selstart.y >= topline && term->selstart.y <= botline) {		term->selstart.y++;		if (term->selstart.y > botline) {		    term->selstart.y = botline + 1;		    term->selstart.x = 0;		}	    }	    if (term->selend.y >= topline && term->selend.y <= botline) {		term->selend.y++;		if (term->selend.y > botline) {		    term->selend.y = botline + 1;		    term->selend.x = 0;		}	    }	    lines++;	}    } else {	while (lines > 0) {	    line = delpos234(term->screen, topline);	    cc_check(line);	       /* XXX-REMOVE-BEFORE-RELEASE */	    if (sb && term->savelines > 0) {		int sblen = count234(term->scrollback);		/*		 * We must add this line to the scrollback. We'll		 * remove a line from the top of the scrollback if		 * the scrollback is full.		 */		if (sblen == term->savelines) {		    unsigned char *cline;		    sblen--;		    cline = delpos234(term->scrollback, 0);		    sfree(cline);		} else		    term->tempsblines += 1;		addpos234(term->scrollback, compressline(line), sblen);		/* now `line' itself can be reused as the bottom line */		/*		 * If the user is currently looking at part of the		 * scrollback, and they haven't enabled any options		 * that are going to reset the scrollback as a		 * result of this movement, then the chances are		 * they'd like to keep looking at the same line. So		 * we move their viewpoint at the same rate as the		 * scroll, at least until their viewpoint hits the		 * top end of the scrollback buffer, at which point		 * we don't have the choice any more.		 * 		 * Thanks to Jan Holmen Holsten for the idea and		 * initial implementation.		 */		if (term->disptop > -term->savelines && term->disptop < 0)		    term->disptop--;	    }            resizeline(term, line, term->cols);	    for (i = 0; i < term->cols; i++)		copy_termchar(line, i, &term->erase_char);	    line->lattr = LATTR_NORM;	    addpos234(term->screen, line, botline);	    /*	     * If the selection endpoints move into the scrollback,	     * we keep them moving until they hit the top. However,	     * of course, if the line _hasn't_ moved into the	     * scrollback then we don't do this, and cut them off	     * at the top of the scroll region.	     * 	     * This applies to selstart and selend (for an existing	     * selection), and also selanchor (for one being	     * selected as we speak).	     */	    seltop = sb ? -term->savelines : topline;	    if (term->selstate != NO_SELECTION) {		if (term->selstart.y >= seltop &&		    term->selstart.y <= botline) {		    term->selstart.y--;		    if (term->selstart.y < seltop) {			term->selstart.y = seltop;			term->selstart.x = 0;		    }		}		if (term->selend.y >= seltop && term->selend.y <= botline) {		    term->selend.y--;		    if (term->selend.y < seltop) {			term->selend.y = seltop;			term->selend.x = 0;		    }		}		if (term->selanchor.y >= seltop &&		    term->selanchor.y <= botline) {		    term->selanchor.y--;		    if (term->selanchor.y < seltop) {			term->selanchor.y = seltop;			term->selanchor.x = 0;		    }		}	    }	    lines--;	}    }#ifdef OPTIMISE_SCROLL    shift += term->disptop - olddisptop;    if (shift < term->rows && shift > -term->rows && shift != 0)	scroll_display(term, topline, botline, shift);#endif /* OPTIMISE_SCROLL */}#ifdef OPTIMISE_SCROLL/* * Add a scroll of a region on the screen into the pending scroll list. * `lines' is +ve for scrolling forward, -ve for backward. * * If the scroll is on the same area as the last scroll in the list, * merge them. */static void save_scroll(Terminal *term, int topline, int botline, int lines){    struct scrollregion *newscroll;    if (term->scrolltail &&	term->scrolltail->topline == topline && 	term->scrolltail->botline == botline) {	term->scrolltail->lines += lines;    } else {	newscroll = snew(struct scrollregion);	newscroll->topline = topline;	newscroll->botline = botline;	newscroll->lines = lines;	newscroll->next = NULL;	if (!term->scrollhead)	    term->scrollhead = newscroll;	else	    term->scrolltail->next = newscroll;	term->scrolltail = newscroll;    }}/* * Scroll the physical display, and our conception of it in disptext. */static void scroll_display(Terminal *term, int topline, int botline, int lines){    int distance, nlines, i, j;    distance = lines > 0 ? lines : -lines;    nlines = botline - topline + 1 - distance;    if (lines > 0) {	for (i = 0; i < nlines; i++)	    for (j = 0; j < term->cols; j++)		copy_termchar(term->disptext[start+i], j,			      term->disptext[start+i+distance]->chars+j);	if (term->dispcursy >= 0 &&	    term->dispcursy >= topline + distance &&	    term->dispcursy < topline + distance + nlines)	    term->dispcursy -= distance;	for (i = 0; i < distance; i++)	    for (j = 0; j < term->cols; j++)		term->disptext[start+nlines+i]->chars[j].attr |= ATTR_INVALID;    } else {	for (i = nlines; i-- ;)	    for (j = 0; j < term->cols; j++)		copy_termchar(term->disptext[start+i+distance], j,			      term->disptext[start+i]->chars+j);	if (term->dispcursy >= 0 &&	    term->dispcursy >= topline &&	    term->dispcursy < topline + nlines)	    term->dispcursy += distance;	for (i = 0; i < distance; i++)	    for (j = 0; j < term->cols; j++)		term->disptext[start+i]->chars[j].attr |= ATTR_INVALID;    }    save_scroll(term, topline, botline, lines);}#endif /* OPTIMISE_SCROLL *//* * Move the cursor to a given position, clipping at boundaries. We * may or may not want to clip at the scroll margin: marg_clip is 0 * not to, 1 to disallow _passing_ the margins, and 2 to disallow * even _being_ outside the margins. */static void move(Terminal *term, int x, int y, int marg_clip){    if (x < 0)	x = 0;    if (x >= term->cols)	x = term->cols - 1;    if (marg_clip) {	if ((term->curs.y >= term->marg_t || marg_clip == 2) &&	    y < term->marg_t)	    y = term->marg_t;	if ((term->curs.y <= term->marg_b || marg_clip == 2) &&	    y > term->marg_b)	    y = term->marg_b;    }    if (y < 0)	y = 0;    if (y >= term->rows)	y = term->rows - 1;    term->curs.x = x;    term->curs.y = y;    term->wrapnext = FALSE;}/* * Save or restore the cursor and SGR mode. */

⌨️ 快捷键说明

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