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

📄 terminal.c

📁 远程登陆工具软件源码 用于远程登陆unix
💻 C
📖 第 1 页 / 共 5 页
字号:
		    term->esc_query = FALSE;
		}
		break;
	      case '\015':	      /* CR: Carriage return */
		term->curs.x = 0;
		term->wrapnext = FALSE;
		fix_cpos;
		term->seen_disp_event = TRUE;
		term->paste_hold = 0;
		if (term->logctx)
		    logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
		break;
	      case '\014':	      /* FF: Form feed */
		if (has_compat(SCOANSI)) {
		    move(term, 0, 0, 0);
		    erase_lots(term, FALSE, FALSE, TRUE);
		    term->disptop = 0;
		    term->wrapnext = FALSE;
		    term->seen_disp_event = 1;
		    break;
		}
	      case '\013':	      /* VT: Line tabulation */
		compatibility(VT100);
	      case '\012':	      /* LF: Line feed */
		if (term->curs.y == term->marg_b)
		    scroll(term, term->marg_t, term->marg_b, 1, TRUE);
		else if (term->curs.y < term->rows - 1)
		    term->curs.y++;
		if (term->cfg.lfhascr)
		    term->curs.x = 0;
		fix_cpos;
		term->wrapnext = FALSE;
		term->seen_disp_event = 1;
		term->paste_hold = 0;
		if (term->logctx)
		    logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
		break;
	      case '\t':	      /* HT: Character tabulation */
		{
		    pos old_curs = term->curs;
		    unsigned long *ldata = lineptr(term->curs.y);

		    do {
			term->curs.x++;
		    } while (term->curs.x < term->cols - 1 &&
			     !term->tabs[term->curs.x]);

		    if ((ldata[term->cols] & LATTR_MODE) != LATTR_NORM) {
			if (term->curs.x >= term->cols / 2)
			    term->curs.x = term->cols / 2 - 1;
		    } else {
			if (term->curs.x >= term->cols)
			    term->curs.x = term->cols - 1;
		    }

		    fix_cpos;
		    check_selection(term, old_curs, term->curs);
		}
		term->seen_disp_event = TRUE;
		break;
	    }
	} else
	    switch (term->termstate) {
	      case TOPLEVEL:
		/* Only graphic characters get this far;
		 * ctrls are stripped above */
		if (term->wrapnext && term->wrap) {
		    term->cpos[1] |= LATTR_WRAPPED;
		    if (term->curs.y == term->marg_b)
			scroll(term, term->marg_t, term->marg_b, 1, TRUE);
		    else if (term->curs.y < term->rows - 1)
			term->curs.y++;
		    term->curs.x = 0;
		    fix_cpos;
		    term->wrapnext = FALSE;
		}
		if (term->insert)
		    insch(term, 1);
		if (term->selstate != NO_SELECTION) {
		    pos cursplus = term->curs;
		    incpos(cursplus);
		    check_selection(term, term->curs, cursplus);
		}
		if (((c & CSET_MASK) == ATTR_ASCII || (c & CSET_MASK) == 0) &&
		    term->logctx)
		    logtraffic(term->logctx, (unsigned char) c, LGTYP_ASCII);
		{
		    int width = 0;
		    if (DIRECT_CHAR(c))
			width = 1;
		    if (!width)
			width = wcwidth((wchar_t) c);
		    switch (width) {
		      case 2:
			/*
			 * If we're about to display a double-width
			 * character starting in the rightmost
			 * column, then we do something special
			 * instead. We must print a space in the
			 * last column of the screen, then wrap;
			 * and we also set LATTR_WRAPPED2 which
			 * instructs subsequent cut-and-pasting not
			 * only to splice this line to the one
			 * after it, but to ignore the space in the
			 * last character position as well.
			 * (Because what was actually output to the
			 * terminal was presumably just a sequence
			 * of CJK characters, and we don't want a
			 * space to be pasted in the middle of
			 * those just because they had the
			 * misfortune to start in the wrong parity
			 * column. xterm concurs.)
			 */
			check_boundary(term, term->curs.x, term->curs.y);
			check_boundary(term, term->curs.x+2, term->curs.y);
			if (term->curs.x == term->cols-1) {
			    *term->cpos++ = ATTR_ASCII | ' ' | term->curr_attr;
			    *term->cpos |= LATTR_WRAPPED | LATTR_WRAPPED2;
			    if (term->curs.y == term->marg_b)
				scroll(term, term->marg_t, term->marg_b,
				       1, TRUE);
			    else if (term->curs.y < term->rows - 1)
				term->curs.y++;
			    term->curs.x = 0;
			    fix_cpos;
			    /* Now we must check_boundary again, of course. */
			    check_boundary(term, term->curs.x, term->curs.y);
			    check_boundary(term, term->curs.x+2, term->curs.y);
			}
			*term->cpos++ = c | term->curr_attr;
			*term->cpos++ = UCSWIDE | term->curr_attr;
			term->curs.x++;
			break;
		      case 1:
			check_boundary(term, term->curs.x, term->curs.y);
			check_boundary(term, term->curs.x+1, term->curs.y);
			*term->cpos++ = c | term->curr_attr;
			break;
		      default:
			continue;
		    }
		}
		term->curs.x++;
		if (term->curs.x == term->cols) {
		    term->cpos--;
		    term->curs.x--;
		    term->wrapnext = TRUE;
		    if (term->wrap && term->vt52_mode) {
			term->cpos[1] |= LATTR_WRAPPED;
			if (term->curs.y == term->marg_b)
			    scroll(term, term->marg_t, term->marg_b, 1, TRUE);
			else if (term->curs.y < term->rows - 1)
			    term->curs.y++;
			term->curs.x = 0;
			fix_cpos;
			term->wrapnext = FALSE;
		    }
		}
		term->seen_disp_event = 1;
		break;

	      case OSC_MAYBE_ST:
		/*
		 * This state is virtually identical to SEEN_ESC, with the
		 * exception that we have an OSC sequence in the pipeline,
		 * and _if_ we see a backslash, we process it.
		 */
		if (c == '\\') {
		    do_osc(term);
		    term->termstate = TOPLEVEL;
		    break;
		}
		/* else fall through */
	      case SEEN_ESC:
		if (c >= ' ' && c <= '/') {
		    if (term->esc_query)
			term->esc_query = -1;
		    else
			term->esc_query = c;
		    break;
		}
		term->termstate = TOPLEVEL;
		switch (ANSI(c, term->esc_query)) {
		  case '[':		/* enter CSI mode */
		    term->termstate = SEEN_CSI;
		    term->esc_nargs = 1;
		    term->esc_args[0] = ARG_DEFAULT;
		    term->esc_query = FALSE;
		    break;
		  case ']':		/* OSC: xterm escape sequences */
		    /* Compatibility is nasty here, xterm, linux, decterm yuk! */
		    compatibility(OTHER);
		    term->termstate = SEEN_OSC;
		    term->esc_args[0] = 0;
		    break;
		  case '7':		/* DECSC: save cursor */
		    compatibility(VT100);
		    save_cursor(term, TRUE);
		    break;
		  case '8':	 	/* DECRC: restore cursor */
		    compatibility(VT100);
		    save_cursor(term, FALSE);
		    term->seen_disp_event = TRUE;
		    break;
		  case '=':		/* DECKPAM: Keypad application mode */
		    compatibility(VT100);
		    term->app_keypad_keys = TRUE;
		    break;
		  case '>':		/* DECKPNM: Keypad numeric mode */
		    compatibility(VT100);
		    term->app_keypad_keys = FALSE;
		    break;
		  case 'D':	       /* IND: exactly equivalent to LF */
		    compatibility(VT100);
		    if (term->curs.y == term->marg_b)
			scroll(term, term->marg_t, term->marg_b, 1, TRUE);
		    else if (term->curs.y < term->rows - 1)
			term->curs.y++;
		    fix_cpos;
		    term->wrapnext = FALSE;
		    term->seen_disp_event = TRUE;
		    break;
		  case 'E':	       /* NEL: exactly equivalent to CR-LF */
		    compatibility(VT100);
		    term->curs.x = 0;
		    if (term->curs.y == term->marg_b)
			scroll(term, term->marg_t, term->marg_b, 1, TRUE);
		    else if (term->curs.y < term->rows - 1)
			term->curs.y++;
		    fix_cpos;
		    term->wrapnext = FALSE;
		    term->seen_disp_event = TRUE;
		    break;
		  case 'M':	       /* RI: reverse index - backwards LF */
		    compatibility(VT100);
		    if (term->curs.y == term->marg_t)
			scroll(term, term->marg_t, term->marg_b, -1, TRUE);
		    else if (term->curs.y > 0)
			term->curs.y--;
		    fix_cpos;
		    term->wrapnext = FALSE;
		    term->seen_disp_event = TRUE;
		    break;
		  case 'Z':	       /* DECID: terminal type query */
		    compatibility(VT100);
		    if (term->ldisc)
			ldisc_send(term->ldisc, term->id_string,
				   strlen(term->id_string), 0);
		    break;
		  case 'c':	       /* RIS: restore power-on settings */
		    compatibility(VT100);
		    power_on(term);
		    if (term->ldisc)   /* cause ldisc to notice changes */
			ldisc_send(term->ldisc, NULL, 0, 0);
		    if (term->reset_132) {
			if (!term->cfg.no_remote_resize)
			    request_resize(term->frontend, 80, term->rows);
			term->reset_132 = 0;
		    }
		    fix_cpos;
		    term->disptop = 0;
		    term->seen_disp_event = TRUE;
		    break;
		  case 'H':	       /* HTS: set a tab */
		    compatibility(VT100);
		    term->tabs[term->curs.x] = TRUE;
		    break;

		  case ANSI('8', '#'):	/* DECALN: fills screen with Es :-) */
		    compatibility(VT100);
		    {
			unsigned long *ldata;
			int i, j;
			pos scrtop, scrbot;

			for (i = 0; i < term->rows; i++) {
			    ldata = lineptr(i);
			    for (j = 0; j < term->cols; j++)
				ldata[j] = ATTR_DEFAULT | 'E';
			    ldata[term->cols] = 0;
			}
			term->disptop = 0;
			term->seen_disp_event = TRUE;
			scrtop.x = scrtop.y = 0;
			scrbot.x = 0;
			scrbot.y = term->rows;
			check_selection(term, scrtop, scrbot);
		    }
		    break;

		  case ANSI('3', '#'):
		  case ANSI('4', '#'):
		  case ANSI('5', '#'):
		  case ANSI('6', '#'):
		    compatibility(VT100);
		    {
			unsigned long nlattr;
			unsigned long *ldata;
			switch (ANSI(c, term->esc_query)) {
			  case ANSI('3', '#'): /* DECDHL: 2*height, top */
			    nlattr = LATTR_TOP;
			    break;
			  case ANSI('4', '#'): /* DECDHL: 2*height, bottom */
			    nlattr = LATTR_BOT;
			    break;
			  case ANSI('5', '#'): /* DECSWL: normal */
			    nlattr = LATTR_NORM;
			    break;
			  default: /* case ANSI('6', '#'): DECDWL: 2*width */
			    nlattr = LATTR_WIDE;
			    break;
			}
			ldata = lineptr(term->curs.y);
			ldata[term->cols] &= ~LATTR_MODE;
			ldata[term->cols] |= nlattr;
		    }
		    break;
		  /* GZD4: G0 designate 94-set */
		  case ANSI('A', '('):
		    compatibility(VT100);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[0] = ATTR_GBCHR;
		    break;
		  case ANSI('B', '('):
		    compatibility(VT100);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[0] = ATTR_ASCII;
		    break;
		  case ANSI('0', '('):
		    compatibility(VT100);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[0] = ATTR_LINEDRW;
		    break;
		  case ANSI('U', '('): 
		    compatibility(OTHER);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[0] = ATTR_SCOACS; 
		    break;
		  /* G1D4: G1-designate 94-set */
		  case ANSI('A', ')'):
		    compatibility(VT100);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[1] = ATTR_GBCHR;
		    break;
		  case ANSI('B', ')'):
		    compatibility(VT100);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[1] = ATTR_ASCII;
		    break;
		  case ANSI('0', ')'):
		    compatibility(VT100);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[1] = ATTR_LINEDRW;
		    break;
		  case ANSI('U', ')'): 
		    compatibility(OTHER);
		    if (!term->cfg.no_remote_charset)
			term->cset_attr[1] = ATTR_SCOACS; 
		    break;
		  /* DOCS: Designate other coding system */
		  case ANSI('8', '%'):	/* Old Linux code */
		  case ANSI('G', '%'):
		    compatibility(OTHER);
		    if (!term->cfg.no_remote_charset)
			term->utf = 1;
		    break;
		  case ANSI('@', '%'):
		    compatibility(OTHER);
		    if (!term->cfg.no_remote_charset)
			term->utf = 0;
		    break;
		}
		break;
	      case SEEN_CSI:
		term->termstate = TOPLEVEL;  /* default */
		if (isdigit(c)) {
		    if (term->esc_nargs <= ARGS_MAX) {
			if (term->esc_args[term->esc_nargs - 1] == ARG_DEFAULT)
			    term->esc_args[term->esc_nargs - 1] = 0;
			term->esc_args[term->esc_nargs - 1] =
			    10 * term->esc_args[term->esc_nargs - 1] + c - '0';
		    }
		    term->termstate = SEEN_CSI;
		} else if (c == ';') {
		    if (++term->esc_nargs <= ARGS_MAX)
			term->esc_args[term->esc_nargs - 1] = ARG_DEFAULT;
		    term->termstate = SEEN_CSI;
		} else if (c < '@') {
		    if (term->esc_query)
			term->esc_query = -1;
		    else if (c == '?')
			term->esc_query = TRUE;
		    else
			term->esc_query = c;
		    term->termstate = SEEN_CSI;
		} else
		    switch (ANSI(c, term->esc_query)) {
		      case 'A':       /* CUU: move up N lines */
			move(term, term->curs.x,
			     term->curs.y - def(term->esc_args[0], 1), 1);
			term->seen_disp_event = TRUE;
			break;
		      case 'e':		/* VPR: move down N lines */
			compatibility(ANSI);
			/* FALLTHROUGH */
		      case 'B':		/* CUD: Cursor down */
			move(term, term->curs.x,
			     term->curs.y + def(term->esc_args[0], 1), 1);
			term->seen_disp_event = TRUE;
			break;
		      case ANSI('c', '>'):	/* DA: report xterm version */
			compatibility(OTHER);
			/* this reports xterm version 136 so that VIM can
			   use the drag messages from the mouse reporting */
			if (term->ldisc)
			    ldisc_send(term->ldisc, "\033[>0;136;0c", 11, 0);
			break;
		      case 'a':		/* HPR: move right N cols */
			compatibility(ANSI);
			/* FALLTHROUGH */
		      case 'C':		/* CUF: Cursor right */ 
			move(term, term->curs.x + def(term->esc_args[0], 1),
			     term->curs.y, 1);
			term->seen_disp_event = TRUE;
			break;
		      case 'D':       /* CUB: move left N cols */
			move(term, term->curs.x - def(term->esc_args[0], 1),
			     term->curs.y, 1);
			term->seen_disp_event = TRUE;
			break;
		      case 'E':

⌨️ 快捷键说明

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