parsestate = groundtable;
VTparse(void){    /* Buffer for processing printable text */    static IChar *print_area;    static size_t print_size, print_used;    /* Buffer for processing strings (e.g., OSC ... ST) */    static Char *string_area;    static size_t string_size, string_used;#if OPT_VT52_MODE    static Bool vt52_cup = FALSE;#endif    Const PARSE_T *groundtable = ansi_table;    TScreen *screen = &term->screen;    Const PARSE_T *parsestate;    unsigned int c;    Char *cp;    int row, col, top, bot, scstype, count;    Bool private_function;	/* distinguish private-mode from standard */    int string_mode;		/* nonzero iff we're processing a string */    int lastchar;		/* positive iff we had a graphic character */    int nextstate;    int laststate;#if OPT_WIDE_CHARS    int last_was_wide;#endif    /* We longjmp back to this point in VTReset() */    (void) setjmp(vtjmpbuf);#if OPT_VT52_MODE    groundtable = screen->vtXX_level ? ansi_table : vt52_table;#else    groundtable = ansi_table;#endif    parsestate = groundtable;    scstype = 0;    private_function = False;    string_mode = 0;    lastchar = -1;		/* not a legal IChar */    nextstate = -1;		/* not a legal state */#if OPT_WIDE_CHARS    last_was_wide = 0;#endif    for (;;) {	int thischar = -1;	c = doinput();#if OPT_WIDE_CHARS	if (screen->wide_chars	    && my_wcwidth(c) == 0) {	    unsigned single = 0;	    int prev, precomposed;	    if (screen->curss) {		dotext(screen, screen->gsets[(int) (screen->curss)],		       print_area, 1);		screen->curss = 0;		single++;	    }	    if (print_used > single) {		dotext(screen,		       screen->gsets[(int) (screen->curgl)],		       print_area + single,		       print_used - single);	    }	    print_used = 0;	    prev = getXtermCell(screen, last_written_row, last_written_col);	    precomposed = do_precomposition(prev, c);	    if (precomposed != -1) {		putXtermCell(screen, last_written_row, last_written_col, precomposed);	    } else {		addXtermCombining(screen,				  last_written_row,				  last_written_col, c);	    }	    if (!screen->scroll_amt)		ScrnRefresh(screen,			    last_written_row,			    last_written_col, 1, 1, 1);	    continue;	}#endif	/* Intercept characters for printer controller mode */	if (screen->printer_controlmode == 2) {	    if ((c = xtermPrinterControl(c)) == 0)		continue;	}	/*	 * VT52 is a little ugly in the one place it has a parameterized	 * control sequence, since the parameter falls after the character	 * that denotes the type of sequence.	 */#if OPT_VT52_MODE	if (vt52_cup) {	    param[nparam++] = (c & 0x7f) - 32;	    if (nparam < 2)		continue;	    vt52_cup = FALSE;	    if ((row = param[0]) < 0)		row = 0;	    if ((col = param[1]) < 0)		col = 0;	    CursorSet(screen, row, col, term->flags);	    parsestate = vt52_table;	    param[0] = 0;	    param[1] = 0;	    continue;	}#endif	/*	 * The parsing tables all have 256 entries.  If we're supporting	 * wide characters, we handle them by treating them the same as	 * printing characters.	 */	laststate = nextstate;#if OPT_WIDE_CHARS	if (c > 255) {	    if (parsestate == groundtable) {		nextstate = CASE_PRINT;	    } else if (parsestate == sos_table) {		c &= 0xffff;		if (c > 255) {		    TRACE(("Found code > 255 while in SOS state: %04X\n", c));		    c = '?';		}	    } else {		nextstate = CASE_GROUND_STATE;	    }	} else#endif	    nextstate = parsestate[E2A(c)];#if OPT_BROKEN_OSC	/*	 * Linux console palette escape sequences start with an OSC, but do	 * not terminate correctly.  Some scripts do not check before writing	 * them, making xterm appear to hang (it's awaiting a valid string	 * terminator).  Just ignore these if we see them - there's no point	 * in emulating bad code.	 */	if (screen->brokenLinuxOSC	    && parsestate == sos_table) {	    if (string_used) {		switch (string_area[0]) {		case 'P':		    if (string_used <= 7)			break;		    /* FALLTHRU */		case 'R':		    parsestate = groundtable;		    nextstate = parsestate[E2A(c)];		    TRACE(("Reset to ground state (brokenLinuxOSC)\n"));		    break;		}	    }	}#endif#if OPT_BROKEN_ST	/*	 * Before patch #171, carriage control embedded within an OSC string	 * would terminate it.  Some (buggy, of course) applications rely on	 * this behavior.  Accommodate them by allowing one to compile xterm	 * and emulate the old behavior.	 */	if (screen->brokenStringTerm	    && parsestate == sos_table	    && c < 32) {	    switch (c) {	    case 5:		/* FALLTHRU */	    case 8:		/* FALLTHRU */	    case 9:		/* FALLTHRU */	    case 10:		/* FALLTHRU */	    case 11:		/* FALLTHRU */	    case 12:		/* FALLTHRU */	    case 13:		/* FALLTHRU */	    case 14:		/* FALLTHRU */	    case 15:		/* FALLTHRU */	    case 24:		parsestate = groundtable;		nextstate = parsestate[E2A(c)];		TRACE(("Reset to ground state (brokenStringTerm)\n"));		break;	    }	}#endif#if OPT_C1_PRINT	/*	 * This is not completely foolproof, but will allow an application	 * with values in the C1 range to use them as printable characters,	 * provided that they are not intermixed with an escape sequence.	 */	if (screen->c1_printable	    && (c >= 128 && c < 160)) {	    nextstate = parsestate[E2A(160)];	    if (nextstate == CASE_ESC_SP_STATE)		nextstate = CASE_ESC_IGNORE;	}#endif#if OPT_WIDE_CHARS	/* if this character is a different width than	   the last one, put the previous text into	   the buffer and draw it now */	if (iswide(c) != last_was_wide) {	    unsigned single = 0;	    if (screen->curss) {		dotext(screen,		       screen->gsets[(int) (screen->curss)],		       print_area, 1);		screen->curss = 0;		single++;	    }	    if (print_used > single) {		dotext(screen,		       screen->gsets[(int) (screen->curgl)],		       print_area + single,		       print_used - single);	    }	    print_used = 0;	}#endif	/*	 * Accumulate string for printable text.  This may be 8/16-bit	 * characters.	 */	if (nextstate == CASE_PRINT) {	    SafeAlloc(IChar, print_area, print_used, print_size);	    if (new_string == 0) {		fprintf(stderr,			"Cannot allocate %d bytes for printable text\n",			new_length);		continue;	    }#if OPT_VT52_MODE	    /*	     * Strip output text to 7-bits for VT52.  We should do this for	     * VT100 also (which is a 7-bit device), but xterm has been	     * doing this for so long we shouldn't change this behavior.	     */	    if (screen->vtXX_level < 1)		c &= 0x7f;#endif	    print_area = new_string;	    print_size = new_length;	    print_area[print_used++] = lastchar = thischar = c;#if OPT_WIDE_CHARS	    last_was_wide = iswide(c);#endif	    if (morePtyData(&VTbuffer)) {		continue;	    }	}	if (nextstate == CASE_PRINT	    || (laststate == CASE_PRINT && print_used)) {	    unsigned single = 0;	    if (screen->curss) {		dotext(screen,		       screen->gsets[(int) (screen->curss)],		       print_area, 1);		screen->curss = 0;		single++;	    }	    if (print_used > single) {		dotext(screen,		       screen->gsets[(int) (screen->curgl)],		       print_area + single,		       print_used - single);	    }	    print_used = 0;	}	/*	 * Accumulate string for APC, DCS, PM, OSC, SOS controls	 * This should always be 8-bit characters.	 */	if (parsestate == sos_table) {	    SafeAlloc(Char, string_area, string_used, string_size);	    if (new_string == 0) {		fprintf(stderr,			"Cannot allocate %d bytes for string mode %d\n",			new_length, string_mode);		continue;	    }#if OPT_WIDE_CHARS	    /*	     * We cannot display codes above 255, but let's try to	     * accommodate the application a little by not aborting the	     * string.	     */	    if ((c & 0xffff) > 255) {		nextstate = CASE_PRINT;		c = '?';	    }#endif	    string_area = new_string;	    string_size = new_length;	    string_area[string_used++] = c;	} else if (parsestate != esc_table) {	    /* if we were accumulating, we're not any more */	    string_mode = 0;	    string_used = 0;	}	TRACE(("parse %04X -> %d\n", c, nextstate));	switch (nextstate) {	case CASE_PRINT:	    /* printable characters (see above) */	    break;	case CASE_GROUND_STATE:	    /* exit ignore mode */	    parsestate = groundtable;	    break;	case CASE_IGNORE:	    /* Ignore character */	    break;	case CASE_ENQ:	    for (count = 0; screen->answer_back[count] != 0; count++)		unparseputc(screen->answer_back[count], screen->respond);	    break;	case CASE_BELL:	    if (string_mode == OSC) {		if (string_used)		    string_area[--string_used] = '\0';		do_osc(string_area, string_used, c);		parsestate = groundtable;	    } else {		/* bell */		Bell(XkbBI_TerminalBell, 0);	    }	    break;	case CASE_BS:	    /* backspace */	    CursorBack(screen, 1);	    break;	case CASE_CR:	    /* carriage return */	    CarriageReturn(screen);	    break;	case CASE_ESC:	    /* escape */	    if_OPT_VT52_MODE(screen, {		parsestate = vt52_esc_table;		break;	    });	    parsestate = esc_table;	    break;#if OPT_VT52_MODE	case CASE_VT52_CUP:	    vt52_cup = TRUE;	    nparam = 0;	    break;	case CASE_VT52_IGNORE:	    parsestate = vt52_ignore_table;	    break;#endif	case CASE_VMOT:	    /*	     * form feed, line feed, vertical tab	     */	    xtermAutoPrint(c);	    xtermIndex(screen, 1);	    if (term->flags & LINEFEED)		CarriageReturn(screen);	    do_xevents();	    break;	case CASE_CBT:	    /* cursor backward tabulation */	    if ((count = param[0]) == DEFAULT)		count = 1;	    while ((count-- > 0)		   && (TabToPrevStop())) ;	    parsestate = groundtable;	    break;	case CASE_CHT:	    /* cursor forward tabulation */	    if ((count = param[0]) == DEFAULT)		count = 1;	    while ((count-- > 0)		   && (TabToNextStop())) ;	    parsestate = groundtable;	    break;	case CASE_TAB:	    /* tab */	    TabToNextStop();	    break;	case CASE_SI:	    screen->curgl = 0;	    if_OPT_VT52_MODE(screen, {		parsestate = groundtable;	    });	    break;	case CASE_SO:	    screen->curgl = 1;	    if_OPT_VT52_MODE(screen, {		parsestate = groundtable;	    });	    break;	case CASE_DECDHL:	    xterm_DECDHL(c == '3');	    parsestate = groundtable;	    break;	case CASE_DECSWL:	    xterm_DECSWL();	    parsestate = groundtable;	    break;	case CASE_DECDWL:	    xterm_DECDWL();	    parsestate = groundtable;	    break;	case CASE_SCR_STATE:	    /* enter scr state */	    parsestate = scrtable;	    break;	case CASE_SCS0_STATE:	    /* enter scs state 0 */	    scstype = 0;	    parsestate = scstable;	    break;	case CASE_SCS1_STATE:	    /* enter scs state 1 */	    scstype = 1;	    parsestate = scstable;	    break;	case CASE_SCS2_STATE:	    /* enter scs state 2 */	    scstype = 2;	    parsestate = scstable;	    break;	case CASE_SCS3_STATE:	    /* enter scs state 3 */	    scstype = 3;	    parsestate = scstable;	    break;	case CASE_ESC_IGNORE:	    /* unknown escape sequence */	    parsestate = eigtable;	    break;	case CASE_ESC_DIGIT:	    /* digit in csi or dec mode */	    if ((row = param[nparam - 1]) == DEFAULT)		row = 0;	    param[nparam - 1] = 10 * row + (c - '0');	    if (param[nparam - 1] > 65535)		param[nparam - 1] = 65535;	    if (parsestate == csi_table)		parsestate = csi2_table;	    break;	case CASE_ESC_SEMI:	    /* semicolon in csi or dec mode */	    if (nparam < NPARAM)		param[nparam++] = DEFAULT;	    if (parsestate == csi_table)		parsestate = csi2_table;	    break;	case CASE_DEC_STATE:	    /* enter dec mode */	    parsestate = dec_table;	    break;	case CASE_DEC2_STATE:	    /* enter dec2 mode */	    parsestate = dec2_table;	    break;	case CASE_DEC3_STATE:	    /* enter dec3 mode */	    parsestate = dec3_table;	    break;	case CASE_ICH:	    /* ICH */	    if ((row = param[0]) < 1)		row = 1;	    InsertChar(screen, row);	    parsestate = groundtable;	    break;	case CASE_CUU:	    /* CUU */	    if ((row = param[0]) < 1)		row = 1;	    CursorUp(screen, row);	    parsestate = groundtable;	    break;	case CASE_CUD:	    /* CUD */	    if ((row = param[0]) < 1)		row = 1;	    CursorDown(screen, row);	    parsestate = groundtable;	    break;	case CASE_CUF:	    /* CUF */	    if ((col = param[0]) < 1)		col = 1;	    CursorForward(screen, col);	    parsestate = groundtable;	    break;	case CASE_CUB:	    /* CUB */	    if ((col = param[0]) < 1)		col = 1;	    CursorBack(screen, col);	    parsestate = groundtable;	    break;	case CASE_CUP:	    /* CUP | HVP */	    if_OPT_XMC_GLITCH(screen, {		Jump_XMC(screen);	    });	    if ((row = param[0]) < 1)		row = 1;	    if (nparam < 2 || (col = param[1]) < 1)		col = 1;	    CursorSet(screen, row - 1, col - 1, term->flags);	    parsestate = groundtable;	    break;	case CASE_VPA:	    if ((row = param[0]) < 1)		row = 1;	    CursorSet(screen, row - 1, screen->cur_col, term->flags);	    parsestate = groundtable;	    break;	case CASE_HPA:	    /* HPA | CHA */	    if ((col = param[0]) < 1)		col = 1;	    CursorSet(screen, screen->cur_row, col - 1, term->flags);	    parsestate = groundtable;	    break;	case CASE_HP_BUGGY_LL:	    /* Some HP-UX applications have the bug that they	       assume ESC F goes to the lower left corner of	       the screen, regardless of what terminfo says. */	    if (screen->hp_ll_bc)		CursorSet(screen, screen->max_row, 0, term->flags);	    parsestate = groundtable;	    break;	case CASE_ED:	    /* ED */	    do_erase_display(screen, param[0], OFF_PROTECT);	    parsestate = groundtable;	    break;	case CASE_EL:	    /* EL */	    do_erase_line(screen, param[0], OFF_PROTECT);	    parsestate = groundtable;	    break;	case CASE_ECH:	    /* ECH */	    ClearRight(screen, param[0] < 1 ? 1 : param[0]);	    parsestate = groundtable;	    break;	case CASE_IL:	    /* IL */	    if ((row = param[0]) < 1)		row = 1;	    InsertLine(screen, row);	    parsestate = groundtable;	    break;	case CASE_DL:	    /* DL */	    if ((row = param[0]) < 1)		row = 1;	    DeleteLine(screen, row);	    parsestate = groundtable;	    break;	case CASE_DCH:	    /* DCH */	    if ((row = param[0]) < 1)		row = 1;	    DeleteChar(screen, row);	    parsestate = groundtable;	    break;	case CASE_TRACK_MOUSE:	    if (screen->send_mouse_pos == VT200_HIGHLIGHT_MOUSE		|| nparam > 1) {		/* Track mouse as long as in window and between		 * specified rows		 */		TrackMouse(param[0],			   param[2] - 1, param[1] - 1,			   param[3] - 1, param[4] - 2);	    } else {		/* SD */		if ((count = param[0]) < 1)		    count = 1;		RevScroll(screen, count);		do_xevents();	    }	    parsestate = groundtable;	    break;	case CASE_DECID:	    if_OPT_VT52_MODE(screen, {		unparseputc(ESC, screen->respond);		unparseputc('/', screen->respond);		unparseputc('Z', screen->respond);		parsestate = groundtable;		break;	    });	    param[0] = -1;	/* Default ID parameter */	    /* FALLTHRU */	case CASE_DA1:	    /* DA1 */	    if (param[0] <= 1) {	/* less than means DEFAULT */		count = 0;		reply.a_type = CSI;		reply.a_pintro = '?';		/* The first param corresponds to the highest		 * operating level (i.e., service level) of the		 * emulation.  A DEC terminal can be setup to		 * respond with a different DA response, but		 * there's no control sequence that modifies this.		 * We set it via a resource.		 */		if (screen->terminal_id < 200) {		    switch (screen->terminal_id) {		    case 102:			reply.a_param[count++] = 6;	/* VT102 */			break;		    case 101:			reply.a_param[count++] = 1;	/* VT101 */			reply.a_param[count++] = 0;	/* no options */			break;		    default:	/* VT100 */			reply.a_param[count++] = 1;	/* VT100 */			reply.a_param[count++] = 2;	/* AVO */			break;		    }		} else {		    reply.a_param[count++] = 60 + screen->terminal_id / 100;		    reply.a_param[count++] = 1;		/* 132-columns */		    reply.a_param[count++] = 2;		/* printer */		    reply.a_param[count++] = 6;		/* selective-erase */#if OPT_SUNPC_KBD		    if (term->keyboard.type == keyboardIsVT220)#endif			reply.a_param[count++] = 8;	/* user-defined-keys */		    reply.a_param[count++] = 9;		/* national replacement charsets */		    reply.a_param[count++] = 15;	/* technical characters */		    if_OPT_ISO_COLORS(screen, {			reply.a_param[count++] = 22;	/* ANSI color, VT525 */		    });#if OPT_DEC_LOCATOR		    reply.a_param[count++] = 29;	/* ANSI text locator */#endif		}		reply.a_nparam = count;		reply.a_inters = 0;		reply.a_final = 'c';		unparseseq(&reply, screen->respond);	    }	    parsestate = groundtable;	    break;	case CASE_DA2:	    /* DA2 */	    if (param[0] <= 0) {	/* less than means DEFAULT */		count = 0;		reply.a_type = CSI;		reply.a_pintro = '>';		if (screen->terminal_id >= 200)		    reply.a_param[count++] = 1;		/* VT220 */		else		    reply.a_param[count++] = 0;		/* VT100 (nonstandard) */		reply.a_param[count++] = XTERM_PATCH;	/* Version */		reply.a_param[count++] = 0;	/* options (none) */		reply.a_nparam = count;		reply.a_inters = 0;		reply.a_final = 'c';		unparseseq(&reply, screen->respond);	    }	    parsestate = groundtable;	    break;	case CASE_DECRPTUI:	    /* DECRPTUI */	    if ((screen->terminal_id >= 400)		&& (param[0] <= 0)) {	/* less than means DEFAULT */		unparseputc1(DCS, screen->respond);		unparseputc('!', screen->respond);		unparseputc('|', screen->respond);		unparseputc('0', screen->respond);		unparseputc1(ST, screen->respond);	    }	    parsestate = groundtable;	    break;	case CASE_TBC:	    /* TBC */	    if ((row = param[0]) <= 0)	/* less than means default */		TabClear(term->tabs, screen->cur_col);	    else if (row == 3)		TabZonk(term->tabs);	    parsestate = groundtable;	    break;	case CASE_SET:	    /* SET */	    ansi_modes(term, bitset);	    parsestate = groundtable;	    break;	case CASE_RST:	    /* RST */	    ansi_modes(term, bitclr);	    parsestate = groundtable;	    break;	case CASE_SGR:	    /* SGR */	    for (row = 0; row < nparam; ++row) {		if_OPT_XMC_GLITCH(screen, {		    Mark_XMC(screen, param[row]);		});		switch (param[row]) {		case DEFAULT:		case 0:		    term->flags &=			~(INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE);		    if_OPT_ISO_COLORS(screen, {			reset_SGR_Colors();		    });		    break;		case 1:	/* Bold                 */		    term->flags |= BOLD;		    if_OPT_ISO_COLORS(screen, {			setExtendedFG();		    });		    break;		case 5:	/* Blink                */		    term->flags |= BLINK;		    if_OPT_ISO_COLORS(screen, {			setExtendedFG();		    });		    break;		case 4:	/* Underscore           */		    term->flags |= UNDERLINE;		    if_OPT_ISO_COLORS(screen, {			setExtendedFG();		    });		    break;		case 7:		    term->flags |= INVERSE;		    if_OPT_ISO_COLORS(screen, {			setExtendedBG();		    });		    break;		case 8:		    term->flags |= INVISIBLE;		    break;		case 22:	/* reset 'bold' */		    term->flags &= ~BOLD;		    if_OPT_ISO_COLORS(screen, {			setExtendedFG();		    });		    break;		case 24:		    term->flags &= ~UNDERLINE;		    if_OPT_ISO_COLORS(screen, {			setExtendedFG();		    });		    break;		case 25:	/* reset 'blink' */		    term->flags &= ~BLINK;		    if_OPT_ISO_COLORS(screen, {			setExtendedFG();		    });		    break;		case 27:		    term->flags &= ~INVERSE;		    if_OPT_ISO_COLORS(screen, {			setExtendedBG();		    });		    break;		case 28:		    term->flags &= ~INVISIBLE;		    break;		case 30:		case 31:		case 32:		case 33:		case 34:		case 35:		case 36:		case 37:		    if_OPT_ISO_COLORS(screen, {			term->sgr_foreground = (param[row] - 30);			term->sgr_extended = 0;			setExtendedFG();		    });		    break;		case 38:		    /* This is more complicated than I'd		       like, but it should properly eat all		       the parameters for unsupported modes		     */		    if_OPT_ISO_COLORS(screen, {			row++;			if (row < nparam) {			    switch (param[row]) {			    case 5:				row++;				if (row < nparam &&				    param[row] < NUM_ANSI_COLORS) {				    term->sgr_foreground = param[row];				    term->sgr_extended = 1;				    setExtendedFG();				}				break;			    default:				row += 7;				break;			    }			}		    });		    break;		case 39:		    if_OPT_ISO_COLORS(screen, {			reset_SGR_Foreground();		    });		    break;		case 40:		case 41:		case 42:		case 43:		case 44:		case 45:		case 46:		case 47:		    if_OPT_ISO_COLORS(screen, {			term->sgr_background = (param[row] - 40);			setExtendedBG();		    });		    break;		case 48:		    if_OPT_ISO_COLORS(screen, {			row++;			if (row < nparam) {			    switch (param[row]) {			    case 5:				row++;				if (row < nparam &&				    param[row] < NUM_ANSI_COLORS) {				    term->sgr_background = param[row];				    setExtendedBG();				}				break;			    default:				row += 7;				break;			    }			}		    });		    break;		case 49:		    if_OPT_ISO_COLORS(screen, {			reset_SGR_Background();		    });		    break;		case 90:		case 91:		case 92:		case 93:		case 94:		case 95:		case 96:		case 97:		    if_OPT_AIX_COLORS(screen, {			term->sgr_foreground = (param[row] - 90 + 8);			term->sgr_extended = 0;			setExtendedFG();		    });		    break;		case 100:#if !OPT_AIX_COLORS		    if_OPT_ISO_COLORS(screen, {			reset_SGR_Foreground();			reset_SGR_Background();		    });		    break;#endif		case 101:		case 102:		case 103:		case 104:		case 105:		case 106:		case 107:		    if_OPT_AIX_COLORS(screen, {			term->sgr_background = (param[row] - 100 + 8);			setExtendedBG();		    });		    break;		}	    }	    parsestate = groundtable;	    break;	    /* DSR (except for the '?') is a superset of CPR */	case CASE_DSR:	    private_function = True;	    /* FALLTHRU */	case CASE_CPR:	    count = 0;	    reply.a_type = CSI;	    reply.a_pintro = private_function ? '?' : 0;	    reply.a_inters = 0;	    reply.a_final = 'n';	    switch (param[0]) {	    case 5:		/* operating status */		reply.a_param[count++] = 0;	/* (no malfunction ;-) */		break;	    case 6:		/* CPR */		/* DECXCPR (with page=0) */		reply.a_param[count++] = screen->cur_row + 1;		reply.a_param[count++] = screen->cur_col + 1;		reply.a_final = 'R';		break;	    case 15:		/* printer status */		reply.a_param[count++] = 13;	/* implement printer */		break;	    case 25:		/* UDK status */		reply.a_param[count++] = 20;	/* UDK always unlocked */		break;	    case 26:		/* keyboard status */		reply.a_param[count++] = 27;		reply.a_param[count++] = 1;	/* North American */		if (screen->terminal_id >= 400) {		    reply.a_param[count++] = 0;		/* ready */		    reply.a_param[count++] = 0;		/* LK201 */		}		break;	    case 53:		/* Locator status */#if OPT_DEC_LOCATOR		reply.a_param[count++] = 50;	/* locator ready */#else		reply.a_param[count++] = 53;	/* no locator */#endif		break;	    }	    if ((reply.a_nparam = count) != 0)		unparseseq(&reply, screen->respond);	    parsestate = groundtable;	    private_function = False;	    break;	case CASE_MC:	    xtermMediaControl(param[0], FALSE);	    parsestate = groundtable;	    break;	case CASE_DEC_MC:	    xtermMediaControl(param[0], TRUE);	    parsestate = groundtable;	    break;	case CASE_HP_MEM_LOCK:	case CASE_HP_MEM_UNLOCK:	    if (screen->scroll_amt)		FlushScroll(screen);	    if (parsestate[c] == CASE_HP_MEM_LOCK)		screen->top_marg = screen->cur_row;	    else		screen->top_marg = 0;	    parsestate = groundtable;	    break;	case CASE_DECSTBM:	    /* DECSTBM - set scrolling region */	    if ((top = param[0]) < 1)		top = 1;	    if (nparam < 2 || (bot = param[1]) == DEFAULT		|| bot > screen->max_row + 1		|| bot == 0)		bot = screen->max_row + 1;	    if (bot > top) {		if (screen->scroll_amt)		    FlushScroll(screen);		screen->top_marg = top - 1;		screen->bot_marg = bot - 1;		CursorSet(screen, 0, 0, term->flags);	    }	    parsestate = groundtable;	    break;	case CASE_DECREQTPARM:	    /* DECREQTPARM */	    if (screen->terminal_id < 200) {	/* VT102 */		if ((row = param[0]) == DEFAULT)		    row = 0;		if (row == 0 || row == 1) {		    reply.a_type = CSI;		    reply.a_pintro = 0;		    reply.a_nparam = 7;		    reply.a_param[0] = row + 2;		    reply.a_param[1] = 1;	/* no parity */		    reply.a_param[2] = 1;	/* eight bits */		    reply.a_param[3] = 128;	/* transmit 38.4k baud */		    reply.a_param[4] = 128;	/* receive 38.4k baud */		    reply.a_param[5] = 1;	/* clock multiplier ? */		    reply.a_param[6] = 0;	/* STP flags ? */		    reply.a_inters = 0;		    reply.a_final = 'x';		    unparseseq(&reply, screen->respond);		}	    }	    parsestate = groundtable;	    break;	case CASE_DECSET:	    /* DECSET */#if OPT_VT52_MODE	    if (screen->vtXX_level != 0)#endif		dpmodes(term, bitset);	    parsestate = groundtable;#if OPT_TEK4014	    if (screen->TekEmu)		return;#endif	    break;	case CASE_DECRST:	    /* DECRST */	    dpmodes(term, bitclr);#if OPT_VT52_MODE	    if (screen->vtXX_level == 0)		groundtable = vt52_table;	    else if (screen->terminal_id >= 100)		groundtable = ansi_table;#endif	    parsestate = groundtable;	    break;	case CASE_DECALN:	    /* DECALN */	    if (screen->cursor_state)		HideCursor();	    for (row = screen->max_row; row >= 0; row--) {		bzero(SCRN_BUF_ATTRS(screen, row),		      col = screen->max_col + 1);		for (cp = SCRN_BUF_CHARS(screen, row); col > 0; col--)		    *cp++ = (Char) 'E';		if_OPT_WIDE_CHARS(screen, {		    bzero(SCRN_BUF_WIDEC(screen, row),			  screen->max_col + 1);		});	    }	    ScrnRefresh(screen, 0, 0, screen->max_row + 1,			screen->max_col + 1, False);	    parsestate = groundtable;	    break;	case CASE_GSETS:	    TRACE(("CASE_GSETS(%d) = '%c'\n", scstype, c));	    if (screen->vtXX_level != 0)		screen->gsets[scstype] = c;	    parsestate = groundtable;	    break;	case CASE_DECSC:	    /* DECSC */	    CursorSave(term);	    parsestate = groundtable;	    break;	case CASE_DECRC:	    /* DECRC */	    CursorRestore(term);	    if_OPT_ISO_COLORS(screen, {		setExtendedFG();	    });	    parsestate = groundtable;	    break;	case CASE_DECKPAM:	    /* DECKPAM */	    term->keyboard.flags |= MODE_DECKPAM;	    update_appkeypad();	    parsestate = groundtable;	    break;	case CASE_DECKPNM:	    /* DECKPNM */	    term->keyboard.flags &= ~MODE_DECKPAM;	    update_appkeypad();	    parsestate = groundtable;	    break;	case CASE_CSI_QUOTE_STATE:	    parsestate = csi_quo_table;	    break;#if OPT_VT52_MODE	case CASE_VT52_FINISH:	    TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",		   screen->terminal_id,		   screen->vtXX_level));	    if (screen->terminal_id >= 100		&& screen->vtXX_level == 0) {		groundtable =		    parsestate = ansi_table;		screen->vtXX_level = screen->vt52_save_level;		screen->curgl = screen->vt52_save_curgl;		screen->curgr = screen->vt52_save_curgr;		screen->curss = screen->vt52_save_curss;		memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets));	    }	    break;#endif	case CASE_ANSI_LEVEL_1:	    set_ansi_conformance(screen, 1);	    parsestate = groundtable;	    break;	case CASE_ANSI_LEVEL_2:	    set_ansi_conformance(screen, 2);	    parsestate = groundtable;	    break;	case CASE_ANSI_LEVEL_3:	    set_ansi_conformance(screen, 3);	    parsestate = groundtable;	    break;	case CASE_DECSCL:	    if (param[0] >= 61 && param[0] <= 65) {		VTReset(TRUE, TRUE);		screen->vtXX_level = param[0] - 60;		if (param[0] > 61) {		    if (param[1] == 1)			show_8bit_control(False);		    else if (param[1] == 0 || param[1] == 2)			show_8bit_control(True);		}	    }	    parsestate = groundtable;	    break;	case CASE_DECSCA:	    screen->protected_mode = DEC_PROTECT;	    if (param[0] <= 0 || param[0] == 2)		term->flags &= ~PROTECTED;	    else if (param[0] == 1)		term->flags |= PROTECTED;	    parsestate = groundtable;	    break;	case CASE_DECSED:	    /* DECSED */	    do_erase_display(screen, param[0], DEC_PROTECT);	    parsestate = groundtable;	    break;	case CASE_DECSEL:	    /* DECSEL */	    do_erase_line(screen, param[0], DEC_PROTECT);	    parsestate = groundtable;	    break;	case CASE_ST:	    if (!string_used)		break;	    string_area[--string_used] = '\0';	    switch (string_mode) {	    case APC:		/* ignored */		break;	    case DCS:		do_dcs(string_area, string_used);		break;	    case OSC:		do_osc(string_area, string_used, ST);		break;	    case PM:		/* ignored */		break;	    case SOS:		/* ignored */		break;	    }	    parsestate = groundtable;	    break;	case CASE_SOS:	    TRACE(("begin SOS: Start of String\n"));	    string_mode = SOS;	    parsestate = sos_table;	    break;	case CASE_PM:	    TRACE(("begin PM: Privacy Message\n"));	    string_mode = PM;	    parsestate = sos_table;	    break;	case CASE_DCS:	    TRACE(("begin DCS: Device Control String\n"));	    string_mode = DCS;	    parsestate = sos_table;	    break;	case CASE_APC:	    TRACE(("begin APC: Application Program Command\n"));	    string_mode = APC;	    parsestate = sos_table;	    break;	case CASE_SPA:	    screen->protected_mode = ISO_PROTECT;	    term->flags |= PROTECTED;	    parsestate = groundtable;	    break;	case CASE_EPA:	    term->flags &= ~PROTECTED;	    parsestate = groundtable;	    break;	case CASE_SU:	    /* SU */	    if ((count = param[0]) < 1)		count = 1;	    xtermScroll(screen, count);	    parsestate = groundtable;	    break;	case CASE_IND:	    /* IND */	    xtermIndex(screen, 1);	    do_xevents();	    parsestate = groundtable;	    break;	case CASE_CPL:	    /* cursor prev line */	    CursorPrevLine(screen, param[0]);	    parsestate = groundtable;	    break;	case CASE_CNL:	    /* cursor next line */	    CursorNextLine(screen, param[0]);	    parsestate = groundtable;	    break;	case CASE_NEL:	    /* NEL */	    xtermIndex(screen, 1);	    CarriageReturn(screen);	    do_xevents();	    parsestate = groundtable;	    break;	case CASE_HTS:	    /* HTS */	    TabSet(term->tabs, screen->cur_col);	    parsestate = groundtable;	    break;	case CASE_RI:	    /* RI */	    RevIndex(screen, 1);	    parsestate = groundtable;	    break;	case CASE_SS2:	    /* SS2 */	    screen->curss = 2;	    parsestate = groundtable;	    break;	case CASE_SS3:	    /* SS3 */	    screen->curss = 3;	    parsestate = groundtable;	    break;	case CASE_CSI_STATE:	    /* enter csi state */	    nparam = 1;	    param[0] = DEFAULT;	    parsestate = csi_table;	    break;	case CASE_ESC_SP_STATE:	    /* esc space */	    parsestate = esc_sp_table;	    break;	case CASE_CSI_EX_STATE:	    /* csi exclamation */	    parsestate = csi_ex_table;	    break;#if OPT_DEC_LOCATOR	case CASE_CSI_TICK_STATE:	    /* csi tick (') */	    parsestate = csi_tick_table;	    break;	case CASE_DECEFR:	    TRACE(("DECEFR - Enable Filter Rectangle\n"));	    if (screen->send_mouse_pos == DEC_LOCATOR) {		MotionOff(screen, term);		if ((screen->loc_filter_top = param[0]) < 1)		    screen->loc_filter_top = LOC_FILTER_POS;		if (nparam < 2 || (screen->loc_filter_left = param[1]) < 1)		    screen->loc_filter_left = LOC_FILTER_POS;		if (nparam < 3 || (screen->loc_filter_bottom = param[2]) < 1)		    screen->loc_filter_bottom = LOC_FILTER_POS;		if (nparam < 4 || (screen->loc_filter_right = param[3]) < 1)		    screen->loc_filter_right = LOC_FILTER_POS;		InitLocatorFilter(term);	    }	    parsestate = groundtable;	    break;	case CASE_DECELR:	    MotionOff(screen, term);	    if (param[0] <= 0 || param[0] > 2) {		screen->send_mouse_pos = MOUSE_OFF;		TRACE(("DECELR - Disable Locator Reports\n"));	    } else {		TRACE(("DECELR - Enable Locator Reports\n"));		screen->send_mouse_pos = DEC_LOCATOR;		if (param[0] == 2) {		    screen->locator_reset = TRUE;		} else {		    screen->locator_reset = FALSE;		}		if (nparam < 2 || param[1] != 1) {		    screen->locator_pixels = FALSE;		} else {		    screen->locator_pixels = TRUE;		}		screen->loc_filter = FALSE;	    }	    parsestate = groundtable;	    break;	case CASE_DECSLE:	    TRACE(("DECSLE - Select Locator Events\n"));	    for (count = 0; count < nparam; ++count) {		switch (param[count]) {		case DEFAULT:		case 0:		    MotionOff(screen, term);		    screen->loc_filter = FALSE;		    screen->locator_events = 0;		    break;		case 1:		    screen->locator_events |= LOC_BTNS_DN;		    break;		case 2:		    screen->locator_events &= ~LOC_BTNS_DN;		    break;		case 3:		    screen->locator_events |= LOC_BTNS_UP;		    break;		case 4:		    screen->locator_events &= ~LOC_BTNS_UP;		    break;		}	    }	    parsestate = groundtable;	    break;	case CASE_DECRQLP:	    TRACE(("DECRQLP - Request Locator Position\n"));	    if (param[0] < 2) {		/* Issue DECLRP Locator Position Report */		GetLocatorPosition(term);	    }	    parsestate = groundtable;	    break;#endif /* OPT_DEC_LOCATOR */	case CASE_S7C1T:	    show_8bit_control(False);	    parsestate = groundtable;	    break;	case CASE_S8C1T:#if OPT_VT52_MODE	    if (screen->vtXX_level <= 1)		break;#endif	    show_8bit_control(True);	    parsestate = groundtable;	    break;	case CASE_OSC:	    TRACE(("begin OSC: Operating System Command\n"));	    parsestate = sos_table;	    string_mode = OSC;	    break;	case CASE_RIS:	    /* RIS */	    VTReset(TRUE, TRUE);	    parsestate = groundtable;	    break;	case CASE_DECSTR:	    /* DECSTR */	    VTReset(FALSE, FALSE);	    parsestate = groundtable;	    break;	case CASE_REP:	    /* REP */	    if (lastchar >= 0 &&		groundtable[E2A(lastchar)] == CASE_PRINT) {		IChar repeated[2];		count = (param[0] < 1) ? 1 : param[0];		repeated[0] = lastchar;		while (count-- > 0) {		    dotext(screen,			   screen->gsets[(int) (screen->curgl)],			   repeated, 1);		}	    }	    parsestate = groundtable;	    break;	case CASE_LS2:	    /* LS2 */	    screen->curgl = 2;	    parsestate = groundtable;	    break;	case CASE_LS3:	    /* LS3 */	    screen->curgl = 3;	    parsestate = groundtable;	    break;	case CASE_LS3R:	    /* LS3R */	    screen->curgr = 3;	    parsestate = groundtable;	    break;	case CASE_LS2R:	    /* LS2R */	    screen->curgr = 2;	    parsestate = groundtable;	    break;	case CASE_LS1R:	    /* LS1R */	    screen->curgr = 1;	    parsestate = groundtable;	    break;	case CASE_XTERM_SAVE:	    savemodes(term);	    parsestate = groundtable;	    break;	case CASE_XTERM_RESTORE:	    restoremodes(term);	    parsestate = groundtable;	    break;	case CASE_XTERM_WINOPS:	    if (screen->allowWindowOps)		window_ops(term);	    parsestate = groundtable;	    break;#if OPT_WIDE_CHARS	case CASE_ESC_PERCENT:	    parsestate = esc_pct_table;	    break;	case CASE_UTF8:	    /* If we did not set UTF-8 mode from resource or the	     * command-line, allow it to be enabled/disabled by	     * control sequence.  To keep the logic simple, require	     * that wide_chars have been set during initialization	     * so that we have been maintaining data structures for	     * wide characters, anyway.  Otherwise we would have to	     * reallocate everything the first time we turned UTF-8	     * mode on.	     */	    if (screen->wide_chars		&& screen->utf8_mode != 2) {		screen->utf8_mode = (c == 'G');		TRACE(("UTF8 mode %s\n",		       screen->utf8_mode ? "ON" : "OFF"));	    } else {		TRACE(("UTF8 mode NOT turned %s (%s)\n",		       (c == 'G') ? "ON" : "OFF",		       (screen->utf8_mode == 2)		       ? "UTF-8 mode set from command-line"		       : "wideChars resource was not set"));	    }	    parsestate = groundtable;	    break;#endif	case CASE_CSI_IGNORE:	    parsestate = cigtable;	    break;	}	if (parsestate == groundtable)	    lastchar = thischar;    }}