+ case SEEN_CSI:
+ termstate = TOPLEVEL; /* default */
+ if (isdigit(c)) {
+ if (esc_nargs <= ARGS_MAX) {
+ if (esc_args[esc_nargs - 1] == ARG_DEFAULT)
+ esc_args[esc_nargs - 1] = 0;
+ esc_args[esc_nargs - 1] =
+ 10 * esc_args[esc_nargs - 1] + c - '0';
+ }
+ termstate = SEEN_CSI;
+ } else if (c == ';') {
+ if (++esc_nargs <= ARGS_MAX)
+ esc_args[esc_nargs - 1] = ARG_DEFAULT;
+ termstate = SEEN_CSI;
+ } else if (c < '@') {
+ if (esc_query)
+ esc_query = -1;
+ else if (c == '?')
+ esc_query = TRUE;
+ else
+ esc_query = c;
+ termstate = SEEN_CSI;
+ } else
+ switch (ANSI(c, esc_query)) {
+ case 'A': /* move up N lines */
+ move(curs.x, curs.y - def(esc_args[0], 1), 1);
+ seen_disp_event = TRUE;
+ break;
+ case 'e': /* move down N lines */
+ compatibility(ANSI);
+ /* FALLTHROUGH */
+ case 'B':
+ move(curs.x, curs.y + def(esc_args[0], 1), 1);
+ seen_disp_event = TRUE;
+ break;
+ case ANSI('c', '>'): /* report xterm version */
+ compatibility(OTHER);
+ /* this reports xterm version 136 so that VIM can
+ use the drag messages from the mouse reporting */
+ ldisc_send("\033[>0;136;0c", 11);
+ break;
+ case 'a': /* move right N cols */
+ compatibility(ANSI);
+ /* FALLTHROUGH */
+ case 'C':
+ move(curs.x + def(esc_args[0], 1), curs.y, 1);
+ seen_disp_event = TRUE;
+ break;
+ case 'D': /* move left N cols */
+ move(curs.x - def(esc_args[0], 1), curs.y, 1);
+ seen_disp_event = TRUE;
+ break;
+ case 'E': /* move down N lines and CR */
+ compatibility(ANSI);
+ move(0, curs.y + def(esc_args[0], 1), 1);
+ seen_disp_event = TRUE;
+ break;
+ case 'F': /* move up N lines and CR */
+ compatibility(ANSI);
+ move(0, curs.y - def(esc_args[0], 1), 1);
+ seen_disp_event = TRUE;
+ break;
+ case 'G':
+ case '`': /* set horizontal posn */
+ compatibility(ANSI);
+ move(def(esc_args[0], 1) - 1, curs.y, 0);
+ seen_disp_event = TRUE;
+ break;
+ case 'd': /* set vertical posn */
+ compatibility(ANSI);
+ move(curs.x,
+ (dec_om ? marg_t : 0) + def(esc_args[0],
+ 1) - 1,
+ (dec_om ? 2 : 0));
+ seen_disp_event = TRUE;
+ break;
+ case 'H':
+ case 'f': /* set horz and vert posns at once */
+ if (esc_nargs < 2)
+ esc_args[1] = ARG_DEFAULT;
+ move(def(esc_args[1], 1) - 1,
+ (dec_om ? marg_t : 0) + def(esc_args[0],
+ 1) - 1,
+ (dec_om ? 2 : 0));
+ seen_disp_event = TRUE;
+ break;
+ case 'J': /* erase screen or parts of it */
+ {
+ unsigned int i = def(esc_args[0], 0) + 1;
+ if (i > 3)
+ i = 0;
+ erase_lots(FALSE, !!(i & 2), !!(i & 1));
+ }
+ disptop = 0;
+ seen_disp_event = TRUE;
+ break;
+ case 'K': /* erase line or parts of it */
+ {
+ unsigned int i = def(esc_args[0], 0) + 1;
+ if (i > 3)
+ i = 0;
+ erase_lots(TRUE, !!(i & 2), !!(i & 1));
+ }
+ seen_disp_event = TRUE;
+ break;
+ case 'L': /* insert lines */
+ compatibility(VT102);
+ if (curs.y <= marg_b)
+ scroll(curs.y, marg_b, -def(esc_args[0], 1),
+ FALSE);
+ fix_cpos;
+ seen_disp_event = TRUE;
+ break;
+ case 'M': /* delete lines */
+ compatibility(VT102);
+ if (curs.y <= marg_b)
+ scroll(curs.y, marg_b, def(esc_args[0], 1),
+ TRUE);
+ fix_cpos;
+ seen_disp_event = TRUE;
+ break;
+ case '@': /* insert chars */
+ /* XXX VTTEST says this is vt220, vt510 manual says vt102 */
+ compatibility(VT102);
+ insch(def(esc_args[0], 1));
+ seen_disp_event = TRUE;
+ break;
+ case 'P': /* delete chars */
+ compatibility(VT102);
+ insch(-def(esc_args[0], 1));
+ seen_disp_event = TRUE;
+ break;
+ case 'c': /* terminal type query */
+ compatibility(VT100);
+ /* This is the response for a VT102 */
+ ldisc_send(id_string, strlen(id_string));
+ break;
+ case 'n': /* cursor position query */
+ if (esc_args[0] == 6) {
+ char buf[32];
+ sprintf(buf, "\033[%d;%dR", curs.y + 1,
+ curs.x + 1);
+ ldisc_send(buf, strlen(buf));
+ } else if (esc_args[0] == 5) {
+ ldisc_send("\033[0n", 4);
+ }
+ break;
+ case 'h': /* toggle modes to high */
+ case ANSI_QUE('h'):
+ compatibility(VT100);
+ {
+ int i;
+ for (i = 0; i < esc_nargs; i++)
+ toggle_mode(esc_args[i], esc_query, TRUE);
+ }
+ break;
+ case 'l': /* toggle modes to low */
+ case ANSI_QUE('l'):
+ compatibility(VT100);
+ {
+ int i;
+ for (i = 0; i < esc_nargs; i++)
+ toggle_mode(esc_args[i], esc_query, FALSE);
+ }
+ break;
+ case 'g': /* clear tabs */
+ compatibility(VT100);
+ if (esc_nargs == 1) {
+ if (esc_args[0] == 0) {
+ tabs[curs.x] = FALSE;
+ } else if (esc_args[0] == 3) {
+ int i;
+ for (i = 0; i < cols; i++)
+ tabs[i] = FALSE;
+ }
+ }
+ break;
+ case 'r': /* set scroll margins */
+ compatibility(VT100);
+ if (esc_nargs <= 2) {
+ int top, bot;
+ top = def(esc_args[0], 1) - 1;
+ bot = (esc_nargs <= 1
+ || esc_args[1] ==
+ 0 ? rows : def(esc_args[1], rows)) - 1;
+ if (bot >= rows)
+ bot = rows - 1;
+ /* VTTEST Bug 9 - if region is less than 2 lines
+ * don't change region.
+ */
+ if (bot - top > 0) {
+ marg_t = top;
+ marg_b = bot;
+ 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
+ */
+ curs.y = (dec_om ? marg_t : 0);
+ fix_cpos;
+ seen_disp_event = TRUE;
+ }
+ }
+ break;
+ case 'm': /* 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 < esc_nargs; i++) {
+ switch (def(esc_args[i], 0)) {
+ case 0: /* restore defaults */
+ curr_attr = ATTR_DEFAULT;
+ break;
+ case 1: /* enable bold */
+ compatibility(VT100AVO);
+ curr_attr |= ATTR_BOLD;
+ break;
+ case 21: /* (enable double underline) */
+ compatibility(OTHER);
+ case 4: /* enable underline */
+ compatibility(VT100AVO);
+ curr_attr |= ATTR_UNDER;
+ break;
+ case 5: /* enable blink */
+ compatibility(VT100AVO);
+ curr_attr |= ATTR_BLINK;
+ break;
+ case 7: /* enable reverse video */
+ curr_attr |= ATTR_REVERSE;
+ break;
+ case 10: /* SCO acs off */
+ compatibility(SCOANSI);
+ sco_acs = 0; break;
+ case 11: /* SCO acs on */
+ compatibility(SCOANSI);
+ sco_acs = 1; break;
+ case 12: /* SCO acs on flipped */
+ compatibility(SCOANSI);
+ sco_acs = 2; break;
+ case 22: /* disable bold */
+ compatibility2(OTHER, VT220);
+ curr_attr &= ~ATTR_BOLD;
+ break;
+ case 24: /* disable underline */
+ compatibility2(OTHER, VT220);
+ curr_attr &= ~ATTR_UNDER;
+ break;
+ case 25: /* disable blink */
+ compatibility2(OTHER, VT220);
+ curr_attr &= ~ATTR_BLINK;
+ break;
+ case 27: /* disable reverse video */
+ compatibility2(OTHER, VT220);
+ curr_attr &= ~ATTR_REVERSE;
+ break;
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ /* foreground */
+ curr_attr &= ~ATTR_FGMASK;
+ curr_attr |=
+ (esc_args[i] - 30) << ATTR_FGSHIFT;
+ break;
+ case 39: /* default-foreground */
+ curr_attr &= ~ATTR_FGMASK;
+ curr_attr |= ATTR_DEFFG;
+ break;
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ /* background */
+ curr_attr &= ~ATTR_BGMASK;
+ curr_attr |=
+ (esc_args[i] - 40) << ATTR_BGSHIFT;
+ break;
+ case 49: /* default-background */
+ curr_attr &= ~ATTR_BGMASK;
+ curr_attr |= ATTR_DEFBG;
+ break;
+ }
+ }
+ if (use_bce)
+ erase_char = (' ' | ATTR_ASCII |
+ (curr_attr &
+ (ATTR_FGMASK | ATTR_BGMASK)));
+ }
+ break;
+ case 's': /* save cursor */
+ save_cursor(TRUE);
+ break;
+ case 'u': /* restore cursor */
+ save_cursor(FALSE);
+ seen_disp_event = TRUE;
+ break;
+ case 't': /* set page size - ie window height */