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

📄 terminal.c

📁 远程登陆工具软件源码 用于远程登陆unix
💻 C
📖 第 1 页 / 共 5 页
字号:
	  case 34:		       /* WYULCURM: Make cursor BIG */
	    compatibility2(OTHER, VT220);
	    term->big_cursor = !state;
	}
}

/*
 * Process an OSC sequence: set window title or icon name.
 */
static void do_osc(Terminal *term)
{
    if (term->osc_w) {
	while (term->osc_strlen--)
	    term->wordness[(unsigned char)
		term->osc_string[term->osc_strlen]] = term->esc_args[0];
    } else {
	term->osc_string[term->osc_strlen] = '\0';
	switch (term->esc_args[0]) {
	  case 0:
	  case 1:
	    if (!term->cfg.no_remote_wintitle)
		set_icon(term->frontend, term->osc_string);
	    if (term->esc_args[0] == 1)
		break;
	    /* fall through: parameter 0 means set both */
	  case 2:
	  case 21:
	    if (!term->cfg.no_remote_wintitle)
		set_title(term->frontend, term->osc_string);
	    break;
	}
    }
}

/*
 * ANSI printing routines.
 */
static void term_print_setup(Terminal *term)
{
    bufchain_clear(&term->printer_buf);
    term->print_job = printer_start_job(term->cfg.printer);
}
static void term_print_flush(Terminal *term)
{
    void *data;
    int len;
    int size;
    while ((size = bufchain_size(&term->printer_buf)) > 5) {
	bufchain_prefix(&term->printer_buf, &data, &len);
	if (len > size-5)
	    len = size-5;
	printer_job_data(term->print_job, data, len);
	bufchain_consume(&term->printer_buf, len);
    }
}
static void term_print_finish(Terminal *term)
{
    void *data;
    int len, size;
    char c;

    if (!term->printing && !term->only_printing)
	return;			       /* we need do nothing */

    term_print_flush(term);
    while ((size = bufchain_size(&term->printer_buf)) > 0) {
	bufchain_prefix(&term->printer_buf, &data, &len);
	c = *(char *)data;
	if (c == '\033' || c == '\233') {
	    bufchain_consume(&term->printer_buf, size);
	    break;
	} else {
	    printer_job_data(term->print_job, &c, 1);
	    bufchain_consume(&term->printer_buf, 1);
	}
    }
    printer_finish_job(term->print_job);
    term->print_job = NULL;
    term->printing = term->only_printing = FALSE;
}

/*
 * Remove everything currently in `inbuf' and stick it up on the
 * in-memory display. There's a big state machine in here to
 * process escape sequences...
 */
void term_out(Terminal *term)
{
    int c, unget;
    unsigned char localbuf[256], *chars;
    int nchars = 0;

    unget = -1;

    chars = NULL;		       /* placate compiler warnings */
    while (nchars > 0 || bufchain_size(&term->inbuf) > 0) {
	if (unget == -1) {
	    if (nchars == 0) {
		void *ret;
		bufchain_prefix(&term->inbuf, &ret, &nchars);
		if (nchars > sizeof(localbuf))
		    nchars = sizeof(localbuf);
		memcpy(localbuf, ret, nchars);
		bufchain_consume(&term->inbuf, nchars);
		chars = localbuf;
		assert(chars != NULL);
	    }
	    c = *chars++;
	    nchars--;

	    /*
	     * Optionally log the session traffic to a file. Useful for
	     * debugging and possibly also useful for actual logging.
	     */
	    if (term->cfg.logtype == LGTYP_DEBUG && term->logctx)
		logtraffic(term->logctx, (unsigned char) c, LGTYP_DEBUG);
	} else {
	    c = unget;
	    unget = -1;
	}

	/* Note only VT220+ are 8-bit VT102 is seven bit, it shouldn't even
	 * be able to display 8-bit characters, but I'll let that go 'cause
	 * of i18n.
	 */

	/*
	 * If we're printing, add the character to the printer
	 * buffer.
	 */
	if (term->printing) {
	    bufchain_add(&term->printer_buf, &c, 1);

	    /*
	     * If we're in print-only mode, we use a much simpler
	     * state machine designed only to recognise the ESC[4i
	     * termination sequence.
	     */
	    if (term->only_printing) {
		if (c == '\033')
		    term->print_state = 1;
		else if (c == (unsigned char)'\233')
		    term->print_state = 2;
		else if (c == '[' && term->print_state == 1)
		    term->print_state = 2;
		else if (c == '4' && term->print_state == 2)
		    term->print_state = 3;
		else if (c == 'i' && term->print_state == 3)
		    term->print_state = 4;
		else
		    term->print_state = 0;
		if (term->print_state == 4) {
		    term_print_finish(term);
		}
		continue;
	    }
	}

	/* First see about all those translations. */
	if (term->termstate == TOPLEVEL) {
	    if (in_utf(term))
		switch (term->utf_state) {
		  case 0:
		    if (c < 0x80) {
			/* UTF-8 must be stateless so we ignore iso2022. */
			if (term->ucsdata->unitab_ctrl[c] != 0xFF) 
			     c = term->ucsdata->unitab_ctrl[c];
			else c = ((unsigned char)c) | ATTR_ASCII;
			break;
		    } else if ((c & 0xe0) == 0xc0) {
			term->utf_size = term->utf_state = 1;
			term->utf_char = (c & 0x1f);
		    } else if ((c & 0xf0) == 0xe0) {
			term->utf_size = term->utf_state = 2;
			term->utf_char = (c & 0x0f);
		    } else if ((c & 0xf8) == 0xf0) {
			term->utf_size = term->utf_state = 3;
			term->utf_char = (c & 0x07);
		    } else if ((c & 0xfc) == 0xf8) {
			term->utf_size = term->utf_state = 4;
			term->utf_char = (c & 0x03);
		    } else if ((c & 0xfe) == 0xfc) {
			term->utf_size = term->utf_state = 5;
			term->utf_char = (c & 0x01);
		    } else {
			c = UCSERR;
			break;
		    }
		    continue;
		  case 1:
		  case 2:
		  case 3:
		  case 4:
		  case 5:
		    if ((c & 0xC0) != 0x80) {
			unget = c;
			c = UCSERR;
			term->utf_state = 0;
			break;
		    }
		    term->utf_char = (term->utf_char << 6) | (c & 0x3f);
		    if (--term->utf_state)
			continue;

		    c = term->utf_char;

		    /* Is somebody trying to be evil! */
		    if (c < 0x80 ||
			(c < 0x800 && term->utf_size >= 2) ||
			(c < 0x10000 && term->utf_size >= 3) ||
			(c < 0x200000 && term->utf_size >= 4) ||
			(c < 0x4000000 && term->utf_size >= 5))
			c = UCSERR;

		    /* Unicode line separator and paragraph separator are CR-LF */
		    if (c == 0x2028 || c == 0x2029)
			c = 0x85;

		    /* High controls are probably a Baaad idea too. */
		    if (c < 0xA0)
			c = 0xFFFD;

		    /* The UTF-16 surrogates are not nice either. */
		    /*       The standard give the option of decoding these: 
		     *       I don't want to! */
		    if (c >= 0xD800 && c < 0xE000)
			c = UCSERR;

		    /* ISO 10646 characters now limited to UTF-16 range. */
		    if (c > 0x10FFFF)
			c = UCSERR;

		    /* This is currently a TagPhobic application.. */
		    if (c >= 0xE0000 && c <= 0xE007F)
			continue;

		    /* U+FEFF is best seen as a null. */
		    if (c == 0xFEFF)
			continue;
		    /* But U+FFFE is an error. */
		    if (c == 0xFFFE || c == 0xFFFF)
			c = UCSERR;

		    /* Oops this is a 16bit implementation */
		    if (c >= 0x10000)
			c = 0xFFFD;
		    break;
	    }
	    /* Are we in the nasty ACS mode? Note: no sco in utf mode. */
	    else if(term->sco_acs && 
		    (c!='\033' && c!='\012' && c!='\015' && c!='\b'))
	    {
	       if (term->sco_acs == 2) c |= 0x80;
	       c |= ATTR_SCOACS;
	    } else {
		switch (term->cset_attr[term->cset]) {
		    /* 
		     * Linedraw characters are different from 'ESC ( B'
		     * only for a small range. For ones outside that
		     * range, make sure we use the same font as well as
		     * the same encoding.
		     */
		  case ATTR_LINEDRW:
		    if (term->ucsdata->unitab_ctrl[c] != 0xFF)
			c = term->ucsdata->unitab_ctrl[c];
		    else
			c = ((unsigned char) c) | ATTR_LINEDRW;
		    break;

		  case ATTR_GBCHR:
		    /* If UK-ASCII, make the '#' a LineDraw Pound */
		    if (c == '#') {
			c = '}' | ATTR_LINEDRW;
			break;
		    }
		  /*FALLTHROUGH*/ case ATTR_ASCII:
		    if (term->ucsdata->unitab_ctrl[c] != 0xFF)
			c = term->ucsdata->unitab_ctrl[c];
		    else
			c = ((unsigned char) c) | ATTR_ASCII;
		    break;
		case ATTR_SCOACS:
		    if (c>=' ') c = ((unsigned char)c) | ATTR_SCOACS;
		    break;
		}
	    }
	}

	/* How about C1 controls ? */
	if ((c & -32) == 0x80 && term->termstate < DO_CTRLS &&
	    !term->vt52_mode && has_compat(VT220)) {
	    term->termstate = SEEN_ESC;
	    term->esc_query = FALSE;
	    c = '@' + (c & 0x1F);
	}

	/* Or the GL control. */
	if (c == '\177' && term->termstate < DO_CTRLS && has_compat(OTHER)) {
	    if (term->curs.x && !term->wrapnext)
		term->curs.x--;
	    term->wrapnext = FALSE;
	    fix_cpos;
	    if (!term->cfg.no_dbackspace)    /* destructive bksp might be disabled */
		*term->cpos = (' ' | term->curr_attr | ATTR_ASCII);
	} else
	    /* Or normal C0 controls. */
	if ((c & -32) == 0 && term->termstate < DO_CTRLS) {
	    switch (c) {
	      case '\005':	       /* ENQ: terminal type query */
		/* Strictly speaking this is VT100 but a VT100 defaults to
		 * no response. Other terminals respond at their option.
		 *
		 * Don't put a CR in the default string as this tends to
		 * upset some weird software.
		 *
		 * An xterm returns "xterm" (5 characters)
		 */
		compatibility(ANSIMIN);
		if (term->ldisc) {
		    char abuf[256], *s, *d;
		    int state = 0;
		    for (s = term->cfg.answerback, d = abuf; *s; s++) {
			if (state) {
			    if (*s >= 'a' && *s <= 'z')
				*d++ = (*s - ('a' - 1));
			    else if ((*s >= '@' && *s <= '_') ||
				     *s == '?' || (*s & 0x80))
				*d++ = ('@' ^ *s);
			    else if (*s == '~')
				*d++ = '^';
			    state = 0;
			} else if (*s == '^') {
			    state = 1;
			} else
			    *d++ = *s;
		    }
		    lpage_send(term->ldisc, DEFAULT_CODEPAGE,
			       abuf, d - abuf, 0);
		}
		break;
	      case '\007':	      /* BEL: Bell */
		{
		    struct beeptime *newbeep;
		    unsigned long ticks;

		    ticks = GETTICKCOUNT();

		    if (!term->beep_overloaded) {
			newbeep = snew(struct beeptime);
			newbeep->ticks = ticks;
			newbeep->next = NULL;
			if (!term->beephead)
			    term->beephead = newbeep;
			else
			    term->beeptail->next = newbeep;
			term->beeptail = newbeep;
			term->nbeeps++;
		    }

		    /*
		     * Throw out any beeps that happened more than
		     * t seconds ago.
		     */
		    while (term->beephead &&
			   term->beephead->ticks < ticks - term->cfg.bellovl_t) {
			struct beeptime *tmp = term->beephead;
			term->beephead = tmp->next;
			sfree(tmp);
			if (!term->beephead)
			    term->beeptail = NULL;
			term->nbeeps--;
		    }

		    if (term->cfg.bellovl && term->beep_overloaded &&
			ticks - term->lastbeep >= (unsigned)term->cfg.bellovl_s) {
			/*
			 * If we're currently overloaded and the
			 * last beep was more than s seconds ago,
			 * leave overload mode.
			 */
			term->beep_overloaded = FALSE;
		    } else if (term->cfg.bellovl && !term->beep_overloaded &&
			       term->nbeeps >= term->cfg.bellovl_n) {
			/*
			 * Now, if we have n or more beeps
			 * remaining in the queue, go into overload
			 * mode.
			 */
			term->beep_overloaded = TRUE;
		    }
		    term->lastbeep = ticks;

		    /*
		     * Perform an actual beep if we're not overloaded.
		     */
		    if (!term->cfg.bellovl || !term->beep_overloaded) {
			beep(term->frontend, term->cfg.beep);
			if (term->cfg.beep == BELL_VISUAL) {
			    term->in_vbell = TRUE;
			    term->vbell_startpoint = ticks;
			    term_update(term);
			}
		    }
		    term->seen_disp_event = TRUE;
		}
		break;
	      case '\b':	      /* BS: Back space */
		if (term->curs.x == 0 &&
		    (term->curs.y == 0 || term->wrap == 0))
		    /* do nothing */ ;
		else if (term->curs.x == 0 && term->curs.y > 0)
		    term->curs.x = term->cols - 1, term->curs.y--;
		else if (term->wrapnext)
		    term->wrapnext = FALSE;
		else
		    term->curs.x--;
		fix_cpos;
		term->seen_disp_event = TRUE;
		break;
	      case '\016':	      /* LS1: Locking-shift one */
		compatibility(VT100);
		term->cset = 1;
		break;
	      case '\017':	      /* LS0: Locking-shift zero */
		compatibility(VT100);
		term->cset = 0;
		break;
	      case '\033':	      /* ESC: Escape */
		if (term->vt52_mode)
		    term->termstate = VT52_ESC;
		else {
		    compatibility(ANSIMIN);
		    term->termstate = SEEN_ESC;

⌨️ 快捷键说明

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