+ 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': /* CNL: move down N lines and CR */
+ compatibility(ANSI);
+ move(term, 0,
+ term->curs.y + def(term->esc_args[0], 1), 1);
+ term->seen_disp_event = TRUE;
+ break;
+ case 'F': /* CPL: move up N lines and CR */
+ compatibility(ANSI);
+ move(term, 0,
+ term->curs.y - def(term->esc_args[0], 1), 1);
+ term->seen_disp_event = TRUE;
+ break;
+ case 'G': /* CHA */
+ case '`': /* HPA: set horizontal posn */
+ compatibility(ANSI);
+ move(term, def(term->esc_args[0], 1) - 1,
+ term->curs.y, 0);
+ term->seen_disp_event = TRUE;
+ break;
+ case 'd': /* VPA: set vertical posn */
+ compatibility(ANSI);
+ move(term, term->curs.x,
+ ((term->dec_om ? term->marg_t : 0) +
+ def(term->esc_args[0], 1) - 1),
+ (term->dec_om ? 2 : 0));
+ term->seen_disp_event = TRUE;
+ break;
+ case 'H': /* CUP */
+ case 'f': /* HVP: set horz and vert posns at once */
+ if (term->esc_nargs < 2)
+ term->esc_args[1] = ARG_DEFAULT;
+ move(term, def(term->esc_args[1], 1) - 1,
+ ((term->dec_om ? term->marg_t : 0) +
+ def(term->esc_args[0], 1) - 1),
+ (term->dec_om ? 2 : 0));
+ term->seen_disp_event = TRUE;
+ break;
+ case 'J': /* ED: erase screen or parts of it */
+ {
+ unsigned int i = def(term->esc_args[0], 0) + 1;
+ if (i > 3)
+ i = 0;
+ erase_lots(term, FALSE, !!(i & 2), !!(i & 1));
+ }
+ term->disptop = 0;
+ term->seen_disp_event = TRUE;
+ break;
+ case 'K': /* EL: erase line or parts of it */
+ {
+ unsigned int i = def(term->esc_args[0], 0) + 1;
+ if (i > 3)
+ i = 0;
+ erase_lots(term, TRUE, !!(i & 2), !!(i & 1));
+ }
+ term->seen_disp_event = TRUE;
+ break;
+ case 'L': /* IL: insert lines */
+ compatibility(VT102);
+ if (term->curs.y <= term->marg_b)
+ scroll(term, term->curs.y, term->marg_b,
+ -def(term->esc_args[0], 1), FALSE);
+ fix_cpos;
+ term->seen_disp_event = TRUE;
+ break;
+ case 'M': /* DL: delete lines */
+ compatibility(VT102);
+ if (term->curs.y <= term->marg_b)
+ scroll(term, term->curs.y, term->marg_b,
+ def(term->esc_args[0], 1),
+ TRUE);
+ fix_cpos;
+ term->seen_disp_event = TRUE;
+ break;
+ case '@': /* ICH: insert chars */
+ /* XXX VTTEST says this is vt220, vt510 manual says vt102 */
+ compatibility(VT102);
+ insch(term, def(term->esc_args[0], 1));
+ term->seen_disp_event = TRUE;
+ break;
+ case 'P': /* DCH: delete chars */
+ compatibility(VT102);
+ insch(term, -def(term->esc_args[0], 1));
+ term->seen_disp_event = TRUE;
+ break;
+ case 'c': /* DA: terminal type query */
+ compatibility(VT100);
+ /* This is the response for a VT102 */
+ if (term->ldisc)
+ ldisc_send(term->ldisc, term->id_string,
+ strlen(term->id_string), 0);
+ break;
+ case 'n': /* DSR: cursor position query */
+ if (term->ldisc) {
+ if (term->esc_args[0] == 6) {
+ char buf[32];
+ sprintf(buf, "\033[%d;%dR", term->curs.y + 1,
+ term->curs.x + 1);
+ ldisc_send(term->ldisc, buf, strlen(buf), 0);
+ } else if (term->esc_args[0] == 5) {
+ ldisc_send(term->ldisc, "\033[0n", 4, 0);
+ }
+ }
+ break;
+ case 'h': /* SM: toggle modes to high */
+ case ANSI_QUE('h'):
+ compatibility(VT100);
+ {
+ int i;
+ for (i = 0; i < term->esc_nargs; i++)
+ toggle_mode(term, term->esc_args[i],
+ term->esc_query, TRUE);
+ }
+ break;
+ case 'i': /* MC: Media copy */
+ case ANSI_QUE('i'):
+ compatibility(VT100);
+ {
+ if (term->esc_nargs != 1) break;
+ if (term->esc_args[0] == 5 && *term->cfg.printer) {
+ term->printing = TRUE;
+ term->only_printing = !term->esc_query;
+ term->print_state = 0;
+ term_print_setup(term);
+ } else if (term->esc_args[0] == 4 &&
+ term->printing) {
+ term_print_finish(term);
+ }
+ }
+ break;
+ case 'l': /* RM: toggle modes to low */
+ case ANSI_QUE('l'):
+ compatibility(VT100);
+ {
+ int i;
+ for (i = 0; i < term->esc_nargs; i++)
+ toggle_mode(term, term->esc_args[i],
+ term->esc_query, FALSE);
+ }
+ break;
+ case 'g': /* TBC: clear tabs */
+ compatibility(VT100);
+ if (term->esc_nargs == 1) {
+ if (term->esc_args[0] == 0) {
+ term->tabs[term->curs.x] = FALSE;
+ } else if (term->esc_args[0] == 3) {
+ int i;
+ for (i = 0; i < term->cols; i++)
+ term->tabs[i] = FALSE;
+ }
+ }
+ break;
+ case 'r': /* DECSTBM: set scroll margins */
+ compatibility(VT100);
+ if (term->esc_nargs <= 2) {
+ int top, bot;
+ top = def(term->esc_args[0], 1) - 1;
+ bot = (term->esc_nargs <= 1
+ || term->esc_args[1] == 0 ?
+ term->rows :
+ def(term->esc_args[1], term->rows)) - 1;
+ if (bot >= term->rows)
+ bot = term->rows - 1;
+ /* VTTEST Bug 9 - if region is less than 2 lines
+ * don't change region.
+ */
+ if (bot - top > 0) {
+ term->marg_t = top;
+ term->marg_b = bot;
+ term->curs.x = 0;
+ /*
+ * I used to think the cursor should be
+ * placed at the top of the newly marginned
+ * area. Apparently not: VMS TPU falls over
+ * if so.
+ *
+ * Well actually it should for
+ * Origin mode - RDB
+ */
+ term->curs.y = (term->dec_om ?
+ term->marg_t : 0);
+ fix_cpos;
+ term->seen_disp_event = TRUE;
+ }
+ }
+ break;
+ case 'm': /* SGR: set graphics rendition */
+ {
+ /*
+ * A VT100 without the AVO only had one
+ * attribute, either underline or
+ * reverse video depending on the
+ * cursor type, this was selected by
+ * CSI 7m.
+ *
+ * case 2:
+ * This is sometimes DIM, eg on the
+ * GIGI and Linux
+ * case 8:
+ * This is sometimes INVIS various ANSI.
+ * case 21:
+ * This like 22 disables BOLD, DIM and INVIS
+ *
+ * The ANSI colours appear on any
+ * terminal that has colour (obviously)
+ * but the interaction between sgr0 and
+ * the colours varies but is usually
+ * related to the background colour
+ * erase item. The interaction between
+ * colour attributes and the mono ones
+ * is also very implementation
+ * dependent.
+ *
+ * The 39 and 49 attributes are likely
+ * to be unimplemented.
+ */
+ int i;
+ for (i = 0; i < term->esc_nargs; i++) {
+ switch (def(term->esc_args[i], 0)) {
+ case 0: /* restore defaults */
+ term->curr_attr = term->default_attr;
+ break;
+ case 1: /* enable bold */
+ compatibility(VT100AVO);
+ term->curr_attr |= ATTR_BOLD;
+ break;
+ case 21: /* (enable double underline) */
+ compatibility(OTHER);
+ case 4: /* enable underline */
+ compatibility(VT100AVO);
+ term->curr_attr |= ATTR_UNDER;
+ break;
+ case 5: /* enable blink */
+ compatibility(VT100AVO);
+ term->curr_attr |= ATTR_BLINK;
+ break;
+ case 6: /* SCO light bkgrd */
+ compatibility(SCOANSI);
+ term->blink_is_real = FALSE;
+ term->curr_attr |= ATTR_BLINK;
+ break;
+ case 7: /* enable reverse video */
+ term->curr_attr |= ATTR_REVERSE;
+ break;
+ case 10: /* SCO acs off */
+ compatibility(SCOANSI);
+ if (term->cfg.no_remote_charset) break;
+ term->sco_acs = 0; break;
+ case 11: /* SCO acs on */
+ compatibility(SCOANSI);
+ if (term->cfg.no_remote_charset) break;
+ term->sco_acs = 1; break;
+ case 12: /* SCO acs on, |0x80 */
+ compatibility(SCOANSI);
+ if (term->cfg.no_remote_charset) break;
+ term->sco_acs = 2; break;
+ case 22: /* disable bold */
+ compatibility2(OTHER, VT220);
+ term->curr_attr &= ~ATTR_BOLD;
+ break;
+ case 24: /* disable underline */
+ compatibility2(OTHER, VT220);
+ term->curr_attr &= ~ATTR_UNDER;
+ break;
+ case 25: /* disable blink */
+ compatibility2(OTHER, VT220);
+ term->curr_attr &= ~ATTR_BLINK;
+ break;
+ case 27: /* disable reverse video */
+ compatibility2(OTHER, VT220);
+ term->curr_attr &= ~ATTR_REVERSE;
+ break;
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ /* foreground */
+ term->curr_attr &= ~ATTR_FGMASK;
+ term->curr_attr |=
+ (term->esc_args[i] - 30)<<ATTR_FGSHIFT;
+ break;
+ case 90:
+ case 91:
+ case 92:
+ case 93:
+ case 94:
+ case 95:
+ case 96:
+ case 97:
+ /* xterm-style bright foreground */
+ term->curr_attr &= ~ATTR_FGMASK;
+ term->curr_attr |=
+ ((term->esc_args[i] - 90 + 16)
+ << ATTR_FGSHIFT);
+ break;
+ case 39: /* default-foreground */
+ term->curr_attr &= ~ATTR_FGMASK;
+ term->curr_attr |= ATTR_DEFFG;
+ break;
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ /* background */
+ term->curr_attr &= ~ATTR_BGMASK;
+ term->curr_attr |=
+ (term->esc_args[i] - 40)<<ATTR_BGSHIFT;
+ break;
+ case 100:
+ case 101:
+ case 102:
+ case 103:
+ case 104:
+ case 105:
+ case 106:
+ case 107:
+ /* xterm-style bright background */
+ term->curr_attr &= ~ATTR_BGMASK;
+ term->curr_attr |=
+ ((term->esc_args[i] - 100 + 16)
+ << ATTR_BGSHIFT);
+ break;
+ case 49: /* default-background */
+ term->curr_attr &= ~ATTR_BGMASK;
+ term->curr_attr |= ATTR_DEFBG;
+ break;
+ }
+ }
+ if (term->use_bce)
+ term->erase_char = (' ' | ATTR_ASCII |
+ (term->curr_attr &
+ (ATTR_FGMASK |
+ ATTR_BGMASK)));
+ }
+ break;
+ case 's': /* save cursor */
+ save_cursor(term, TRUE);
+ break;
+ case 'u': /* restore cursor */
+ save_cursor(term, FALSE);
+ term->seen_disp_event = TRUE;
+ break;
+ case 't': /* DECSLPP: set page size - ie window height */
+ /*
+ * VT340/VT420 sequence DECSLPP, DEC only allows values
+ * 24/25/36/48/72/144 other emulators (eg dtterm) use
+ * illegal values (eg first arg 1..9) for window changing
+ * and reports.
+ */
+ if (term->esc_nargs <= 1
+ && (term->esc_args[0] < 1 ||
+ term->esc_args[0] >= 24)) {
+ compatibility(VT340TEXT);
+ if (!term->cfg.no_remote_resize)
+ request_resize(term->frontend, term->cols,
+ def(term->esc_args[0], 24));
+ deselect(term);
+ } else if (term->esc_nargs >= 1 &&
+ term->esc_args[0] >= 1 &&
+ term->esc_args[0] < 24) {
+ compatibility(OTHER);
+
+ switch (term->esc_args[0]) {
+ int x, y, len;
+ char buf[80], *p;
+ case 1:
+ set_iconic(term->frontend, FALSE);
+ break;
+ case 2:
+ set_iconic(term->frontend, TRUE);
+ break;
+ case 3:
+ if (term->esc_nargs >= 3) {
+ if (!term->cfg.no_remote_resize)
+ move_window(term->frontend,
+ def(term->esc_args[1], 0),
+ def(term->esc_args[2], 0));
+ }
+ break;
+ case 4:
+ /* We should resize the window to a given
+ * size in pixels here, but currently our
+ * resizing code isn't healthy enough to
+ * manage it. */
+ break;
+ case 5:
+ /* move to top */
+ set_zorder(term->frontend, TRUE);
+ break;
+ case 6:
+ /* move to bottom */
+ set_zorder(term->frontend, FALSE);
+ break;
+ case 7:
+ refresh_window(term->frontend);
+ break;
+ case 8:
+ if (term->esc_nargs >= 3) {
+ if (!term->cfg.no_remote_resize)
+ request_resize(term->frontend,
+ def(term->esc_args[2], term->cfg.width),
+ def(term->esc_args[1], term->cfg.height));
+ }
+ break;
+ case 9:
+ if (term->esc_nargs >= 2)
+ set_zoomed(term->frontend,
+ term->esc_args[1] ?
+ TRUE : FALSE);
+ break;
+ case 11:
+ if (term->ldisc)
+ ldisc_send(term->ldisc,
+ is_iconic(term->frontend) ?
+ "\033[1t" : "\033[2t", 4, 0);
+ break;
+ case 13:
+ if (term->ldisc) {
+ get_window_pos(term->frontend, &x, &y);
+ len = sprintf(buf, "\033[3;%d;%dt", x, y);
+ ldisc_send(term->ldisc, buf, len, 0);
+ }
+ break;
+ case 14:
+ if (term->ldisc) {
+ get_window_pixels(term->frontend, &x, &y);
+ len = sprintf(buf, "\033[4;%d;%dt", x, y);
+ ldisc_send(term->ldisc, buf, len, 0);
+ }
+ break;
+ case 18:
+ if (term->ldisc) {
+ len = sprintf(buf, "\033[8;%d;%dt",
+ term->rows, term->cols);
+ ldisc_send(term->ldisc, buf, len, 0);
+ }
+ break;
+ case 19:
+ /*
+ * Hmmm. Strictly speaking we
+ * should return `the size of the
+ * screen in characters', but
+ * that's not easy: (a) window
+ * furniture being what it is it's
+ * hard to compute, and (b) in
+ * resize-font mode maximising the
+ * window wouldn't change the
+ * number of characters. *shrug*. I
+ * think we'll ignore it for the
+ * moment and see if anyone
+ * complains, and then ask them
+ * what they would like it to do.
+ */
+ break;
+ case 20:
+ if (term->ldisc &&
+ !term->cfg.no_remote_qtitle) {
+ p = get_window_title(term->frontend, TRUE);
+ len = strlen(p);
+ ldisc_send(term->ldisc, "\033]L", 3, 0);
+ ldisc_send(term->ldisc, p, len, 0);
+ ldisc_send(term->ldisc, "\033\\", 2, 0);
+ }
+ break;
+ case 21:
+ if (term->ldisc &&
+ !term->cfg.no_remote_qtitle) {
+ p = get_window_title(term->frontend,FALSE);
+ len = strlen(p);
+ ldisc_send(term->ldisc, "\033]l", 3, 0);
+ ldisc_send(term->ldisc, p, len, 0);
+ ldisc_send(term->ldisc, "\033\\", 2, 0);
+ }
+ break;
+ }
+ }
+ break;
+ case 'S': /* SU: Scroll up */
+ compatibility(SCOANSI);
+ scroll(term, term->marg_t, term->marg_b,
+ def(term->esc_args[0], 1), TRUE);
+ fix_cpos;
+ term->wrapnext = FALSE;
+ term->seen_disp_event = TRUE;
+ break;
+ case 'T': /* SD: Scroll down */
+ compatibility(SCOANSI);
+ scroll(term, term->marg_t, term->marg_b,
+ -def(term->esc_args[0], 1), TRUE);
+ fix_cpos;
+ term->wrapnext = FALSE;
+ term->seen_disp_event = TRUE;
+ break;
+ case ANSI('|', '*'): /* DECSNLS */
+ /*
+ * Set number of lines on screen
+ * VT420 uses VGA like hardware and can
+ * support any size in reasonable range
+ * (24..49 AIUI) with no default specified.
+ */
+ compatibility(VT420);
+ if (term->esc_nargs == 1 && term->esc_args[0] > 0) {
+ if (!term->cfg.no_remote_resize)
+ request_resize(term->frontend, term->cols,
+ def(term->esc_args[0],
+ term->cfg.height));
+ deselect(term);
+ }
+ break;
+ case ANSI('|', '$'): /* DECSCPP */
+ /*
+ * Set number of columns per page
+ * Docs imply range is only 80 or 132, but
+ * I'll allow any.
+ */
+ compatibility(VT340TEXT);
+ if (term->esc_nargs <= 1) {
+ if (!term->cfg.no_remote_resize)
+ request_resize(term->frontend,
+ def(term->esc_args[0],
+ term->cfg.width), term->rows);
+ deselect(term);
+ }
+ break;
+ case 'X': /* ECH: write N spaces w/o moving cursor */
+ /* XXX VTTEST says this is vt220, vt510 manual
+ * says vt100 */
+ compatibility(ANSIMIN);
+ {
+ int n = def(term->esc_args[0], 1);
+ pos cursplus;
+ unsigned long *p = term->cpos;
+ if (n > term->cols - term->curs.x)
+ n = term->cols - term->curs.x;
+ cursplus = term->curs;
+ cursplus.x += n;
+ check_boundary(term, term->curs.x, term->curs.y);
+ check_boundary(term, term->curs.x+n, term->curs.y);
+ check_selection(term, term->curs, cursplus);
+ while (n--)
+ *p++ = term->erase_char;
+ term->seen_disp_event = TRUE;
+ }
+ break;
+ case 'x': /* DECREQTPARM: report terminal characteristics */
+ compatibility(VT100);
+ if (term->ldisc) {
+ char buf[32];
+ int i = def(term->esc_args[0], 0);
+ if (i == 0 || i == 1) {
+ strcpy(buf, "\033[2;1;1;112;112;1;0x");
+ buf[2] += i;
+ ldisc_send(term->ldisc, buf, 20, 0);
+ }
+ }
+ break;
+ case 'Z': /* CBT: BackTab for xterm */
+ compatibility(OTHER);
+ {
+ int i = def(term->esc_args[0], 1);
+ pos old_curs = term->curs;
+
+ for(;i>0 && term->curs.x>0; i--) {
+ do {
+ term->curs.x--;
+ } while (term->curs.x >0 &&
+ !term->tabs[term->curs.x]);
+ }
+ fix_cpos;
+ check_selection(term, old_curs, term->curs);
+ }
+ break;
+ case ANSI('c', '='): /* Hide or Show Cursor */
+ compatibility(SCOANSI);
+ switch(term->esc_args[0]) {
+ case 0: /* hide cursor */
+ term->cursor_on = FALSE;
+ break;
+ case 1: /* restore cursor */
+ term->big_cursor = FALSE;
+ term->cursor_on = TRUE;
+ break;
+ case 2: /* block cursor */
+ term->big_cursor = TRUE;
+ term->cursor_on = TRUE;
+ break;
+ }
+ break;
+ case ANSI('C', '='):
+ /*
+ * set cursor start on scanline esc_args[0] and
+ * end on scanline esc_args[1].If you set
+ * the bottom scan line to a value less than
+ * the top scan line, the cursor will disappear.
+ */
+ compatibility(SCOANSI);
+ if (term->esc_nargs >= 2) {
+ if (term->esc_args[0] > term->esc_args[1])
+ term->cursor_on = FALSE;
+ else
+ term->cursor_on = TRUE;
+ }
+ break;
+ case ANSI('D', '='):
+ compatibility(SCOANSI);
+ term->blink_is_real = FALSE;
+ if (term->esc_args[0]>=1)
+ term->curr_attr |= ATTR_BLINK;
+ else
+ term->curr_attr &= ~ATTR_BLINK;
+ break;
+ case ANSI('E', '='):
+ compatibility(SCOANSI);
+ term->blink_is_real = (term->esc_args[0] >= 1);
+ break;
+ case ANSI('F', '='): /* set normal foreground */
+ compatibility(SCOANSI);
+ if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
+ long colour =
+ (sco2ansicolour[term->esc_args[0] & 0x7] |
+ ((term->esc_args[0] & 0x8) << 1)) <<
+ ATTR_FGSHIFT;
+ term->curr_attr &= ~ATTR_FGMASK;
+ term->curr_attr |= colour;
+ term->default_attr &= ~ATTR_FGMASK;
+ term->default_attr |= colour;
+ }
+ break;
+ case ANSI('G', '='): /* set normal background */
+ compatibility(SCOANSI);
+ if (term->esc_args[0] >= 0 && term->esc_args[0] < 16) {
+ long colour =
+ (sco2ansicolour[term->esc_args[0] & 0x7] |
+ ((term->esc_args[0] & 0x8) << 1)) <<
+ ATTR_BGSHIFT;
+ term->curr_attr &= ~ATTR_BGMASK;
+ term->curr_attr |= colour;
+ term->default_attr &= ~ATTR_BGMASK;
+ term->default_attr |= colour;
+ }
+ break;
+ case ANSI('L', '='):
+ compatibility(SCOANSI);
+ term->use_bce = (term->esc_args[0] <= 0);
+ term->erase_char = ERASE_CHAR;
+ if (term->use_bce)
+ term->erase_char = (' ' | ATTR_ASCII |
+ (term->curr_attr &
+ (ATTR_FGMASK | ATTR_BGMASK)));
+ break;
+ case ANSI('p', '"'): /* DECSCL: set compat level */
+ /*
+ * Allow the host to make this emulator a
+ * 'perfect' VT102. This first appeared in
+ * the VT220, but we do need to get back to
+ * PuTTY mode so I won't check it.
+ *
+ * The arg in 40..42,50 are a PuTTY extension.
+ * The 2nd arg, 8bit vs 7bit is not checked.
+ *
+ * Setting VT102 mode should also change
+ * the Fkeys to generate PF* codes as a
+ * real VT102 has no Fkeys. The VT220 does
+ * this, F11..F13 become ESC,BS,LF other
+ * Fkeys send nothing.
+ *
+ * Note ESC c will NOT change this!
+ */
+
+ switch (term->esc_args[0]) {
+ case 61:
+ term->compatibility_level &= ~TM_VTXXX;
+ term->compatibility_level |= TM_VT102;
+ break;
+ case 62:
+ term->compatibility_level &= ~TM_VTXXX;
+ term->compatibility_level |= TM_VT220;
+ break;
+
+ default:
+ if (term->esc_args[0] > 60 &&
+ term->esc_args[0] < 70)
+ term->compatibility_level |= TM_VTXXX;
+ break;
+
+ case 40:
+ term->compatibility_level &= TM_VTXXX;
+ break;
+ case 41:
+ term->compatibility_level = TM_PUTTY;
+ break;
+ case 42:
+ term->compatibility_level = TM_SCOANSI;
+ break;
+
+ case ARG_DEFAULT:
+ term->compatibility_level = TM_PUTTY;
+ break;
+ case 50:
+ break;
+ }
+
+ /* Change the response to CSI c */
+ if (term->esc_args[0] == 50) {
+ int i;
+ char lbuf[64];
+ strcpy(term->id_string, "\033[?");
+ for (i = 1; i < term->esc_nargs; i++) {
+ if (i != 1)
+ strcat(term->id_string, ";");
+ sprintf(lbuf, "%d", term->esc_args[i]);
+ strcat(term->id_string, lbuf);
+ }
+ strcat(term->id_string, "c");
+ }
+#if 0
+ /* Is this a good idea ?
+ * Well we should do a soft reset at this point ...
+ */
+ if (!has_compat(VT420) && has_compat(VT100)) {
+ if (!term->cfg.no_remote_resize) {
+ if (term->reset_132)
+ request_resize(132, 24);
+ else
+ request_resize(80, 24);
+ }
+ }
+#endif
+ break;
+ }