"Fossies" - the Fresh Open Source Software Archive

Member "xterm-356/charproc.c" (2 May 2020, 350195 Bytes) of package /linux/misc/xterm-356.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "charproc.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 355_vs_356.

    1 /* $XTermId: charproc.c,v 1.1748 2020/05/02 16:26:20 tom Exp $ */
    2 
    3 /*
    4  * Copyright 1999-2019,2020 by Thomas E. Dickey
    5  *
    6  *                         All Rights Reserved
    7  *
    8  * Permission is hereby granted, free of charge, to any person obtaining a
    9  * copy of this software and associated documentation files (the
   10  * "Software"), to deal in the Software without restriction, including
   11  * without limitation the rights to use, copy, modify, merge, publish,
   12  * distribute, sublicense, and/or sell copies of the Software, and to
   13  * permit persons to whom the Software is furnished to do so, subject to
   14  * the following conditions:
   15  *
   16  * The above copyright notice and this permission notice shall be included
   17  * in all copies or substantial portions of the Software.
   18  *
   19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   22  * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
   23  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   26  *
   27  * Except as contained in this notice, the name(s) of the above copyright
   28  * holders shall not be used in advertising or otherwise to promote the
   29  * sale, use or other dealings in this Software without prior written
   30  * authorization.
   31  *
   32  *
   33  * Copyright 1988  X Consortium
   34  *
   35  * Permission to use, copy, modify, distribute, and sell this software and its
   36  * documentation for any purpose is hereby granted without fee, provided that
   37  * the above copyright notice appear in all copies and that both that
   38  * copyright notice and this permission notice appear in supporting
   39  * documentation.
   40  *
   41  * The above copyright notice and this permission notice shall be included in
   42  * all copies or substantial portions of the Software.
   43  *
   44  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   45  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   46  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
   47  * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
   48  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   49  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   50  *
   51  * Except as contained in this notice, the name of the X Consortium shall not be
   52  * used in advertising or otherwise to promote the sale, use or other dealings
   53  * in this Software without prior written authorization from the X Consortium.
   54  *
   55  */
   56 /*
   57  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
   58  *
   59  *                         All Rights Reserved
   60  *
   61  * Permission to use, copy, modify, and distribute this software and its
   62  * documentation for any purpose and without fee is hereby granted,
   63  * provided that the above copyright notice appear in all copies and that
   64  * both that copyright notice and this permission notice appear in
   65  * supporting documentation, and that the name of Digital Equipment
   66  * Corporation not be used in advertising or publicity pertaining to
   67  * distribution of the software without specific, written prior permission.
   68  *
   69  *
   70  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   71  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   72  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   73  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   74  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   75  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   76  * SOFTWARE.
   77  */
   78 
   79 /* charproc.c */
   80 
   81 #include <version.h>
   82 #include <xterm.h>
   83 
   84 #include <X11/Xatom.h>
   85 #include <X11/Xutil.h>
   86 #include <X11/cursorfont.h>
   87 #include <X11/Xmu/Atoms.h>
   88 #include <X11/Xmu/CharSet.h>
   89 #include <X11/Xmu/Converters.h>
   90 
   91 #if OPT_INPUT_METHOD
   92 
   93 #if defined(HAVE_LIB_XAW)
   94 #include <X11/Xaw/XawImP.h>
   95 #elif defined(HAVE_LIB_XAW3D)
   96 #include <X11/Xaw3d/XawImP.h>
   97 #elif defined(HAVE_LIB_XAW3DXFT)
   98 #include <X11/Xaw3dxft/XawImP.h>
   99 #elif defined(HAVE_LIB_NEXTAW)
  100 #include <X11/neXtaw/XawImP.h>
  101 #elif defined(HAVE_LIB_XAWPLUS)
  102 #include <X11/XawPlus/XawImP.h>
  103 #endif
  104 
  105 #endif
  106 
  107 #if OPT_WIDE_CHARS
  108 #include <xutf8.h>
  109 #include <wcwidth.h>
  110 #include <precompose.h>
  111 #ifdef HAVE_LANGINFO_CODESET
  112 #include <langinfo.h>
  113 #endif
  114 #endif
  115 
  116 #if USE_DOUBLE_BUFFER
  117 #include <X11/extensions/Xdbe.h>
  118 #endif
  119 
  120 #include <stdio.h>
  121 #include <ctype.h>
  122 #include <assert.h>
  123 
  124 #if defined(HAVE_SCHED_YIELD)
  125 #include <sched.h>
  126 #endif
  127 
  128 #include <VTparse.h>
  129 #include <data.h>
  130 #include <error.h>
  131 #include <menu.h>
  132 #include <main.h>
  133 #include <fontutils.h>
  134 #include <charclass.h>
  135 #include <xstrings.h>
  136 #include <graphics.h>
  137 
  138 typedef int (*BitFunc) (unsigned * /* p */ ,
  139             unsigned /* mask */ );
  140 
  141 static IChar doinput(XtermWidget /* xw */ );
  142 static int set_character_class(char * /*s */ );
  143 static void FromAlternate(XtermWidget /* xw */ );
  144 static void ReallyReset(XtermWidget /* xw */ ,
  145             Bool /* full */ ,
  146             Bool /* saved */ );
  147 static void RequestResize(XtermWidget /* xw */ ,
  148               int /* rows */ ,
  149               int /* cols */ ,
  150               Bool /* text */ );
  151 static void SwitchBufs(XtermWidget /* xw */ ,
  152                int /* toBuf */ ,
  153                Bool /* clearFirst */ );
  154 static void ToAlternate(XtermWidget /* xw */ ,
  155             Bool /* clearFirst */ );
  156 static void ansi_modes(XtermWidget /* xw */ ,
  157                BitFunc /* func */ );
  158 static int bitclr(unsigned *p, unsigned mask);
  159 static int bitcpy(unsigned *p, unsigned q, unsigned mask);
  160 static int bitset(unsigned *p, unsigned mask);
  161 static void dpmodes(XtermWidget /* xw */ ,
  162             BitFunc /* func */ );
  163 static void restoremodes(XtermWidget /* xw */ );
  164 static void savemodes(XtermWidget /* xw */ );
  165 static void window_ops(XtermWidget /* xw */ );
  166 
  167 #if OPT_BLINK_CURS || OPT_BLINK_TEXT
  168 #define SettableCursorBlink(screen) \
  169     (((screen)->cursor_blink != cbAlways) && \
  170      ((screen)->cursor_blink != cbNever))
  171 #define UpdateCursorBlink(xw) \
  172      SetCursorBlink(xw, TScreenOf(xw)->cursor_blink)
  173 static void SetCursorBlink(XtermWidget /* xw */ ,
  174                BlinkOps /* enable */ );
  175 static void HandleBlinking(XtPointer /* closure */ ,
  176                XtIntervalId * /* id */ );
  177 static void StartBlinking(XtermWidget /* xw */ );
  178 static void StopBlinking(XtermWidget /* xw */ );
  179 #else
  180 #define StartBlinking(xw)   /* nothing */
  181 #define StopBlinking(xw)    /* nothing */
  182 #endif
  183 
  184 #ifndef NO_ACTIVE_ICON
  185 static Boolean discount_frame_extents(XtermWidget /* xw */ ,
  186                       int * /* height */ ,
  187                       int * /* width */ );
  188 #else
  189 #define discount_frame_extents(xw, height, width)   False
  190 #endif
  191 
  192 #if OPT_INPUT_METHOD
  193 static void PreeditPosition(XtermWidget /* xw */ );
  194 #endif
  195 
  196 #define DEFAULT     -1
  197 #define BELLSUPPRESSMSEC 200
  198 
  199 static ANSI reply;
  200 static PARAMS parms;
  201 
  202 #define nparam parms.count
  203 
  204 #define InitParams()  init_params()
  205 #define GetParam(n)   parms.params[(n)]
  206 #define SetParam(n,v) parms.params[(n)] = v
  207 #define ParamPair(n)  nparam - (n), parms.params + (n)
  208 
  209 static jmp_buf vtjmpbuf;
  210 
  211 /* event handlers */
  212 static void HandleBell PROTO_XT_ACTIONS_ARGS;
  213 static void HandleIgnore PROTO_XT_ACTIONS_ARGS;
  214 static void HandleKeymapChange PROTO_XT_ACTIONS_ARGS;
  215 static void HandleVisualBell PROTO_XT_ACTIONS_ARGS;
  216 #if HANDLE_STRUCT_NOTIFY
  217 static void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS;
  218 #endif
  219 
  220 /*
  221  * NOTE: VTInitialize zeros out the entire ".screen" component of the
  222  * XtermWidget, so make sure to add an assignment statement in VTInitialize()
  223  * for each new ".screen" field added to this resource list.
  224  */
  225 
  226 /* Defaults */
  227 #if OPT_ISO_COLORS
  228 
  229 /*
  230  * If we default to colorMode enabled, compile-in defaults for the ANSI colors.
  231  */
  232 #if DFT_COLORMODE
  233 #define DFT_COLOR(name) name
  234 #else
  235 #define DFT_COLOR(name) XtDefaultForeground
  236 #endif
  237 #endif
  238 
  239 static char _Font_Selected_[] = "yes";  /* string is arbitrary */
  240 
  241 static const char *defaultTranslations;
  242 /* *INDENT-OFF* */
  243 static XtActionsRec actionsList[] = {
  244     { "allow-bold-fonts",   HandleAllowBoldFonts },
  245     { "allow-send-events",  HandleAllowSends },
  246     { "bell",           HandleBell },
  247     { "clear-saved-lines",  HandleClearSavedLines },
  248     { "copy-selection",     HandleCopySelection },
  249     { "create-menu",        HandleCreateMenu },
  250     { "delete-is-del",      HandleDeleteIsDEL },
  251     { "dired-button",       DiredButton },
  252     { "hard-reset",     HandleHardReset },
  253     { "ignore",         HandleIgnore },
  254     { "insert",         HandleKeyPressed },  /* alias for insert-seven-bit */
  255     { "insert-eight-bit",   HandleEightBitKeyPressed },
  256     { "insert-selection",   HandleInsertSelection },
  257     { "insert-seven-bit",   HandleKeyPressed },
  258     { "interpret",      HandleInterpret },
  259     { "keymap",         HandleKeymapChange },
  260     { "popup-menu",     HandlePopupMenu },
  261     { "print",          HandlePrintScreen },
  262     { "print-everything",   HandlePrintEverything },
  263     { "print-redir",        HandlePrintControlMode },
  264     { "quit",           HandleQuit },
  265     { "redraw",         HandleRedraw },
  266     { "scroll-back",        HandleScrollBack },
  267     { "scroll-forw",        HandleScrollForward },
  268     { "scroll-to",      HandleScrollTo },
  269     { "secure",         HandleSecure },
  270     { "select-cursor-end",  HandleKeyboardSelectEnd },
  271     { "select-cursor-extend",   HandleKeyboardSelectExtend },
  272     { "select-cursor-start",    HandleKeyboardSelectStart },
  273     { "select-end",     HandleSelectEnd },
  274     { "select-extend",      HandleSelectExtend },
  275     { "select-set",     HandleSelectSet },
  276     { "select-start",       HandleSelectStart },
  277     { "send-signal",        HandleSendSignal },
  278     { "set-8-bit-control",  Handle8BitControl },
  279     { "set-allow132",       HandleAllow132 },
  280     { "set-altscreen",      HandleAltScreen },
  281     { "set-appcursor",      HandleAppCursor },
  282     { "set-appkeypad",      HandleAppKeypad },
  283     { "set-autolinefeed",   HandleAutoLineFeed },
  284     { "set-autowrap",       HandleAutoWrap },
  285     { "set-backarrow",      HandleBackarrow },
  286     { "set-bellIsUrgent",   HandleBellIsUrgent },
  287     { "set-cursesemul",     HandleCursesEmul },
  288     { "set-jumpscroll",     HandleJumpscroll },
  289     { "set-keep-clipboard", HandleKeepClipboard },
  290     { "set-keep-selection", HandleKeepSelection },
  291     { "set-marginbell",     HandleMarginBell },
  292     { "set-old-function-keys",  HandleOldFunctionKeys },
  293     { "set-pop-on-bell",    HandleSetPopOnBell },
  294     { "set-reverse-video",  HandleReverseVideo },
  295     { "set-reversewrap",    HandleReverseWrap },
  296     { "set-scroll-on-key",  HandleScrollKey },
  297     { "set-scroll-on-tty-output", HandleScrollTtyOutput },
  298     { "set-scrollbar",      HandleScrollbar },
  299     { "set-select",     HandleSetSelect },
  300     { "set-sun-keyboard",   HandleSunKeyboard },
  301     { "set-titeInhibit",    HandleTiteInhibit },
  302     { "set-visual-bell",    HandleSetVisualBell },
  303     { "set-vt-font",        HandleSetFont },
  304     { "soft-reset",     HandleSoftReset },
  305     { "start-cursor-extend",    HandleKeyboardStartExtend },
  306     { "start-extend",       HandleStartExtend },
  307     { "string",         HandleStringEvent },
  308     { "vi-button",      ViButton },
  309     { "visual-bell",        HandleVisualBell },
  310 #ifdef ALLOWLOGGING
  311     { "set-logging",        HandleLogging },
  312 #endif
  313 #if OPT_ALLOW_XXX_OPS
  314     { "allow-color-ops",    HandleAllowColorOps },
  315     { "allow-font-ops",     HandleAllowFontOps },
  316     { "allow-mouse-ops",    HandleAllowMouseOps },
  317     { "allow-tcap-ops",     HandleAllowTcapOps },
  318     { "allow-title-ops",    HandleAllowTitleOps },
  319     { "allow-window-ops",   HandleAllowWindowOps },
  320 #endif
  321 #if OPT_BLINK_CURS
  322     { "set-cursorblink",    HandleCursorBlink },
  323 #endif
  324 #if OPT_BOX_CHARS
  325     { "set-font-linedrawing",   HandleFontBoxChars },
  326     { "set-font-packed",    HandleFontPacked },
  327 #endif
  328 #if OPT_DABBREV
  329     { "dabbrev-expand",     HandleDabbrevExpand },
  330 #endif
  331 #if OPT_DEC_CHRSET
  332     { "set-font-doublesize",    HandleFontDoublesize },
  333 #endif
  334 #if OPT_DEC_SOFTFONT
  335     { "set-font-loading",   HandleFontLoading },
  336 #endif
  337 #if OPT_SCREEN_DUMPS
  338     { "dump-html",          HandleDumpHtml },
  339     { "dump-svg",           HandleDumpSvg },
  340 #endif
  341 #if OPT_EXEC_XTERM
  342     { "spawn-new-terminal", HandleSpawnTerminal },
  343 #endif
  344 #if OPT_HP_FUNC_KEYS
  345     { "set-hp-function-keys",   HandleHpFunctionKeys },
  346 #endif
  347 #if OPT_LOAD_VTFONTS
  348     { "load-vt-fonts",      HandleLoadVTFonts },
  349 #endif
  350 #if OPT_MAXIMIZE
  351     { "deiconify",      HandleDeIconify },
  352     { "fullscreen",     HandleFullscreen },
  353     { "iconify",        HandleIconify },
  354     { "maximize",       HandleMaximize },
  355     { "restore",        HandleRestoreSize },
  356 #endif
  357 #if OPT_NUM_LOCK
  358     { "alt-sends-escape",   HandleAltEsc },
  359     { "meta-sends-escape",  HandleMetaEsc },
  360     { "set-num-lock",       HandleNumLock },
  361 #endif
  362 #ifdef OPT_PRINT_ON_EXIT
  363     { "print-immediate",    HandlePrintImmediate },
  364     { "print-on-error",     HandlePrintOnError },
  365 #endif
  366 #if OPT_READLINE
  367     { "readline-button",    ReadLineButton },
  368 #endif
  369 #if OPT_RENDERFONT
  370     { "set-render-font",    HandleRenderFont },
  371 #endif
  372 #if OPT_SCO_FUNC_KEYS
  373     { "set-sco-function-keys",  HandleScoFunctionKeys },
  374 #endif
  375 #if OPT_SCROLL_LOCK
  376     { "scroll-lock",        HandleScrollLock },
  377 #endif
  378 #if OPT_SELECTION_OPS
  379     { "exec-formatted",     HandleExecFormatted },
  380     { "exec-selectable",    HandleExecSelectable },
  381     { "insert-formatted",   HandleInsertFormatted },
  382     { "insert-selectable",  HandleInsertSelectable },
  383 #endif
  384 #if OPT_SHIFT_FONTS
  385     { "larger-vt-font",     HandleLargerFont },
  386     { "smaller-vt-font",    HandleSmallerFont },
  387 #endif
  388 #if OPT_SIXEL_GRAPHICS
  389     { "set-sixel-scrolling",    HandleSixelScrolling },
  390 #endif
  391 #if OPT_GRAPHICS
  392     { "set-private-colors", HandleSetPrivateColorRegisters },
  393 #endif
  394 #if OPT_SUN_FUNC_KEYS
  395     { "set-sun-function-keys",  HandleSunFunctionKeys },
  396 #endif
  397 #if OPT_TEK4014
  398     { "set-terminal-type",  HandleSetTerminalType },
  399     { "set-visibility",     HandleVisibility },
  400     { "set-tek-text",       HandleSetTekText },
  401     { "tek-page",       HandleTekPage },
  402     { "tek-reset",      HandleTekReset },
  403     { "tek-copy",       HandleTekCopy },
  404 #endif
  405 #if OPT_TOOLBAR
  406     { "set-toolbar",        HandleToolbar },
  407 #endif
  408 #if OPT_WIDE_CHARS
  409     { "set-utf8-mode",      HandleUTF8Mode },
  410     { "set-utf8-fonts",     HandleUTF8Fonts },
  411     { "set-utf8-title",     HandleUTF8Title },
  412 #endif
  413 };
  414 /* *INDENT-ON* */
  415 
  416 #define SPS screen.printer_state
  417 
  418 static XtResource xterm_resources[] =
  419 {
  420     Bres(XtNallowPasteControls, XtCAllowPasteControls,
  421      screen.allowPasteControl0, False),
  422     Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False),
  423     Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR),
  424     Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT),
  425     Bres(XtNallowMouseOps, XtCAllowMouseOps, screen.allowMouseOp0, DEF_ALLOW_MOUSE),
  426     Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP),
  427     Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE),
  428     Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW),
  429     Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False),
  430     Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC),
  431     Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True),
  432     Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False),
  433     Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False),
  434     Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False),
  435     Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False),
  436     Bres(XtNalternateScroll, XtCScrollCond, screen.alternateScroll, False),
  437     Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True),
  438     Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False),
  439     Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False),
  440     Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_BS),
  441     Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False),
  442     Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True),
  443     Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True),
  444     Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False),
  445     Bres(XtNc132, XtCC132, screen.c132, False),
  446     Bres(XtNcdXtraScroll, XtCCdXtraScroll, misc.cdXtraScroll, False),
  447     Bres(XtNcolorInnerBorder, XtCColorInnerBorder, misc.color_inner_border, False),
  448     Bres(XtNcurses, XtCCurses, screen.curses, False),
  449     Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True),
  450     Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine,
  451      screen.cutToBeginningOfLine, True),
  452     Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL),
  453     Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True),
  454     Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False),
  455     Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True),
  456     Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True),
  457     Bres(XtNeraseSavedLines, XtCEraseSavedLines, screen.eraseSavedLines0, True),
  458     Bres(XtNhighlightSelection, XtCHighlightSelection,
  459      screen.highlight_selection, False),
  460     Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False),
  461     Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False),
  462     Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True),
  463     Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False),
  464     Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True),
  465     Bres(XtNkeepClipboard, XtCKeepClipboard, screen.keepClipboard, False),
  466     Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True),
  467     Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False),
  468     Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False),
  469     Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC),
  470     Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False),
  471     Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False),
  472     Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False),
  473     Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False),
  474     Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False),
  475     Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False),
  476     Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True),
  477     Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False),
  478     Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False),
  479     Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False),
  480     Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False),
  481     Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False),
  482     Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True),
  483     Bres(XtNselectToClipboard, XtCSelectToClipboard,
  484      screen.selectToClipboard, False),
  485     Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False),
  486     Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False),
  487     Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False),
  488     Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False),
  489     Bres(XtNunderLine, XtCUnderLine, screen.underline, True),
  490     Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False),
  491     Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False),
  492 
  493     Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"),
  494 
  495     Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC),
  496     Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource),
  497     Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER),
  498     Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1),
  499     Ires(XtNlimitResponse, XtCLimitResponse, screen.unparse_max, DEF_LIMIT_RESPONSE),
  500     Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME),
  501     Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL),
  502     Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE),
  503     Ires(XtNprinterControlMode, XtCPrinterControlMode,
  504      SPS.printer_controlmode, 0),
  505     Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES),
  506     Ires(XtNnextEventDelay, XtCNextEventDelay, screen.nextEventDelay, 1),
  507     Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100),
  508     Ires(XtNsaveLines, XtCSaveLines, screen.savelines, DEF_SAVE_LINES),
  509     Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1),
  510     Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, DEF_SCROLL_LINES),
  511 
  512     Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL),
  513     Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL),
  514     Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL),
  515     Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL),
  516     Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL),
  517     Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL),
  518     Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL),
  519 
  520     Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""),
  521     Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT),
  522     Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
  523     Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
  524     Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
  525     Sres(XtNdisallowedColorOps, XtCDisallowedColorOps,
  526      screen.disallowedColorOps, DEF_DISALLOWED_COLOR),
  527     Sres(XtNdisallowedFontOps, XtCDisallowedFontOps,
  528      screen.disallowedFontOps, DEF_DISALLOWED_FONT),
  529     Sres(XtNdisallowedMouseOps, XtCDisallowedMouseOps,
  530      screen.disallowedMouseOps, DEF_DISALLOWED_MOUSE),
  531     Sres(XtNdisallowedPasteControls, XtCDisallowedPasteControls,
  532      screen.disallowedPasteControls, DEF_DISALLOWED_PASTE_CONTROLS),
  533     Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps,
  534      screen.disallowedTcapOps, DEF_DISALLOWED_TCAP),
  535     Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
  536      screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
  537     Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META),
  538     Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
  539      screen.eightbit_select_types, NULL),
  540     Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
  541     Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL),
  542     Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT),
  543     Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""),
  544     Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL),
  545 
  546     Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground),
  547     Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground),
  548     Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground),
  549     Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground),
  550     Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground),
  551 
  552     {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity),
  553      XtOffsetOf(XtermWidgetRec, misc.resizeGravity),
  554      XtRImmediate, (XtPointer) SouthWestGravity},
  555 
  556     {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor),
  557      XtOffsetOf(XtermWidgetRec, screen.pointer_cursor),
  558      XtRString, (XtPointer) "xterm"},
  559 
  560 #ifdef ALLOWLOGGING
  561     Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False),
  562     Bres(XtNlogging, XtCLogging, misc.log_on, False),
  563     Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL),
  564 #endif
  565 
  566 #ifndef NO_ACTIVE_ICON
  567     Sres("activeIcon", "ActiveIcon", misc.active_icon_s, "default"),
  568     Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2),
  569     Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"),
  570     Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground),
  571 #endif              /* NO_ACTIVE_ICON */
  572 
  573 #if OPT_BLINK_CURS
  574     Bres(XtNcursorBlinkXOR, XtCCursorBlinkXOR, screen.cursor_blink_xor, True),
  575     Sres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink_s, "false"),
  576 #endif
  577     Bres(XtNcursorUnderLine, XtCCursorUnderLine, screen.cursor_underline, False),
  578 
  579 #if OPT_BLINK_TEXT
  580     Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD),
  581 #endif
  582 
  583 #if OPT_BLINK_CURS || OPT_BLINK_TEXT
  584     Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600),
  585     Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300),
  586 #endif
  587 
  588 #if OPT_BOX_CHARS
  589     Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False),
  590     Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True),
  591     Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False),
  592     Bres(XtNassumeAllChars, XtCAssumeAllChars, screen.assume_all_chars, True),
  593 #endif
  594 
  595 #if OPT_BROKEN_OSC
  596     Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True),
  597 #endif
  598 
  599 #if OPT_BROKEN_ST
  600     Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False),
  601 #endif
  602 
  603 #if OPT_C1_PRINT
  604     Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False),
  605 #endif
  606 
  607 #if OPT_CLIP_BOLD
  608     Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True),
  609     Bres(XtNuseBorderClipping, XtCUseBorderClipping,
  610      screen.use_border_clipping, False),
  611 #endif
  612 
  613 #if OPT_DEC_CHRSET
  614     Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True),
  615     Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET),
  616 #endif
  617 
  618 #if OPT_DEC_RECTOPS
  619     Ires(XtNchecksumExtension, XtCChecksumExtension, screen.checksum_ext0, csDEC),
  620 #endif
  621 
  622 #if OPT_HIGHLIGHT_COLOR
  623     Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground),
  624     Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground),
  625     Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True),
  626     Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe),
  627 #endif              /* OPT_HIGHLIGHT_COLOR */
  628 
  629 #if OPT_INPUT_METHOD
  630     Bres(XtNopenIm, XtCOpenIm, misc.open_im, True),
  631     Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL),
  632     Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type,
  633      "OverTheSpot,Root"),
  634     Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3),
  635 #endif
  636 
  637 #if OPT_ISO_COLORS
  638     Bres(XtNboldColors, XtCColorMode, screen.boldColors, True),
  639     Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0),
  640     Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE),
  641 
  642     Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False),
  643     Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False),
  644     Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False),
  645     Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False),
  646     Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False),
  647     Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False),
  648 #if OPT_WIDE_ATTRS
  649     Bres(XtNcolorITMode, XtCColorAttrMode, screen.colorITMode, False),
  650 #endif
  651 #if OPT_DIRECT_COLOR
  652     Bres(XtNdirectColor, XtCDirectColor, screen.direct_color, True),
  653 #endif
  654 
  655     COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")),
  656     COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")),
  657     COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")),
  658     COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")),
  659     COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)),
  660     COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")),
  661     COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")),
  662     COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")),
  663     COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")),
  664     COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")),
  665     COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")),
  666     COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")),
  667     COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)),
  668     COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")),
  669     COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")),
  670     COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")),
  671     COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)),
  672     COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)),
  673     COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)),
  674     COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)),
  675 
  676 #if OPT_WIDE_ATTRS
  677     COLOR_RES("IT", screen.Acolors[COLOR_IT], DFT_COLOR(XtDefaultForeground)),
  678 #endif
  679 
  680 #if !OPT_COLOR_RES2
  681 #if OPT_256_COLORS
  682 # include <256colres.h>
  683 #elif OPT_88_COLORS
  684 # include <88colres.h>
  685 #endif
  686 #endif              /* !OPT_COLOR_RES2 */
  687 
  688 #endif              /* OPT_ISO_COLORS */
  689 
  690     CLICK_RES("2", screen.onClick[1], "word"),
  691     CLICK_RES("3", screen.onClick[2], "line"),
  692     CLICK_RES("4", screen.onClick[3], 0),
  693     CLICK_RES("5", screen.onClick[4], 0),
  694 
  695 #if OPT_MOD_FKEYS
  696     Ires(XtNmodifyKeyboard, XtCModifyKeyboard,
  697      keyboard.modify_1st.allow_keys, 0),
  698     Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys,
  699      keyboard.modify_1st.cursor_keys, 2),
  700     Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys,
  701      keyboard.modify_1st.function_keys, 2),
  702     Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys,
  703      keyboard.modify_1st.keypad_keys, 0),
  704     Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys,
  705      keyboard.modify_1st.other_keys, 0),
  706     Ires(XtNmodifyStringKeys, XtCModifyStringKeys,
  707      keyboard.modify_1st.string_keys, 0),
  708     Ires(XtNformatOtherKeys, XtCFormatOtherKeys,
  709      keyboard.format_keys, 0),
  710 #endif
  711 
  712 #if OPT_NUM_LOCK
  713     Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False),
  714     Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True),
  715 #endif
  716 
  717 #if OPT_PRINT_COLORS
  718     Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1),
  719 #endif
  720 
  721 #if OPT_REGIS_GRAPHICS
  722     Sres(XtNregisDefaultFont, XtCRegisDefaultFont,
  723      screen.graphics_regis_default_font, ""),
  724     Sres(XtNregisScreenSize, XtCRegisScreenSize,
  725      screen.graphics_regis_screensize, "auto"),
  726 #endif
  727 
  728 #if OPT_GRAPHICS
  729     Sres(XtNmaxGraphicSize, XtCMaxGraphicSize, screen.graphics_max_size,
  730      "1000x1000"),
  731 #endif
  732 
  733 #if OPT_SHIFT_FONTS
  734     Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True),
  735 #endif
  736 
  737 #if OPT_SIXEL_GRAPHICS
  738     Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, True),
  739     Bres(XtNsixelScrollsRight, XtCSixelScrollsRight,
  740      screen.sixel_scrolls_right, False),
  741 #endif
  742 
  743 #if OPT_GRAPHICS
  744     Ires(XtNnumColorRegisters, XtCNumColorRegisters,
  745      screen.numcolorregisters, 0),
  746     Bres(XtNprivateColorRegisters, XtCPrivateColorRegisters,
  747      screen.privatecolorregisters, True),
  748 #endif
  749 
  750 #if OPT_SUNPC_KBD
  751     Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10),
  752 #endif
  753 
  754 #if OPT_TEK4014
  755     Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False),
  756     Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False),
  757     Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False),
  758 #endif
  759 
  760 #if OPT_TOOLBAR
  761     Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0),
  762     Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25),
  763 #endif
  764 
  765 #if OPT_WIDE_CHARS
  766     Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False),
  767     Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False),
  768     Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True),
  769     Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False),
  770     Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
  771     Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
  772     Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
  773     Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 655),
  774     Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 65536),
  775     Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"),
  776     Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"),
  777     Sres(XtNutf8Title, XtCUtf8Title, screen.utf8_title_s, "default"),
  778     Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
  779     Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT),
  780     Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL),
  781 #endif
  782 
  783 #if OPT_LUIT_PROG
  784     Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"),
  785     Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER),
  786 #endif
  787 
  788 #if OPT_INPUT_METHOD
  789     Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT),
  790 #endif
  791 
  792 #if OPT_SCROLL_LOCK
  793     Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False),
  794 #endif
  795 
  796     /* these are used only for testing ncurses, not in the manual page */
  797 #if OPT_XMC_GLITCH
  798     Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False),
  799     Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True),
  800     Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1),
  801     Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0),
  802 #endif
  803 
  804 #ifdef SCROLLBAR_RIGHT
  805     Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False),
  806 #endif
  807 
  808 #if OPT_RENDERFONT
  809     Bres(XtNforceXftHeight, XtCForceXftHeight, screen.force_xft_height, False),
  810 #define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0")
  811     RES_FACESIZE(1),
  812     RES_FACESIZE(2),
  813     RES_FACESIZE(3),
  814     RES_FACESIZE(4),
  815     RES_FACESIZE(5),
  816     RES_FACESIZE(6),
  817     Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE),
  818     Sres(XtNfaceName, XtCFaceName, misc.default_xft.f_n, DEFFACENAME),
  819     Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"),
  820     Ires(XtNlimitFontsets, XtCLimitFontsets, misc.limit_fontsets, DEF_XFT_CACHE),
  821 #if OPT_RENDERWIDE
  822     Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.default_xft.f_w, DEFFACENAME),
  823 #endif
  824 #endif
  825 };
  826 
  827 static Boolean VTSetValues(Widget cur, Widget request, Widget new_arg,
  828                ArgList args, Cardinal *num_args);
  829 static void VTClassInit(void);
  830 static void VTDestroy(Widget w);
  831 static void VTExpose(Widget w, XEvent *event, Region region);
  832 static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args,
  833              Cardinal *num_args);
  834 static void VTRealize(Widget w, XtValueMask * valuemask,
  835               XSetWindowAttributes * values);
  836 static void VTResize(Widget w);
  837 
  838 #if OPT_INPUT_METHOD
  839 static void VTInitI18N(XtermWidget);
  840 #endif
  841 
  842 #ifdef VMS
  843 globaldef {
  844     "xtermclassrec"
  845 } noshare
  846 
  847 #else
  848 static
  849 #endif              /* VMS */
  850 WidgetClassRec xtermClassRec =
  851 {
  852     {
  853     /* core_class fields */
  854     (WidgetClass) & widgetClassRec,     /* superclass   */
  855     "VT100",        /* class_name                   */
  856     sizeof(XtermWidgetRec), /* widget_size                  */
  857     VTClassInit,        /* class_initialize             */
  858     NULL,           /* class_part_initialize        */
  859     False,          /* class_inited                 */
  860     VTInitialize,       /* initialize                   */
  861     NULL,           /* initialize_hook              */
  862     VTRealize,      /* realize                      */
  863     actionsList,        /* actions                      */
  864     XtNumber(actionsList),  /* num_actions                  */
  865     xterm_resources,    /* resources                    */
  866     XtNumber(xterm_resources),  /* num_resources        */
  867     NULLQUARK,      /* xrm_class                    */
  868     True,           /* compress_motion              */
  869     False,          /* compress_exposure            */
  870     True,           /* compress_enterleave          */
  871     False,          /* visible_interest             */
  872     VTDestroy,      /* destroy                      */
  873     VTResize,       /* resize                       */
  874     VTExpose,       /* expose                       */
  875     VTSetValues,        /* set_values                   */
  876     NULL,           /* set_values_hook              */
  877     XtInheritSetValuesAlmost,   /* set_values_almost    */
  878     NULL,           /* get_values_hook              */
  879     NULL,           /* accept_focus                 */
  880     XtVersion,      /* version                      */
  881     NULL,           /* callback_offsets             */
  882     0,          /* tm_table                     */
  883     XtInheritQueryGeometry, /* query_geometry               */
  884     XtInheritDisplayAccelerator,    /* display_accelerator  */
  885     NULL            /* extension                    */
  886     }
  887 };
  888 
  889 #ifdef VMS
  890 globaldef {
  891     "xtermwidgetclass"
  892 }
  893 noshare
  894 #endif /* VMS */
  895 WidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec;
  896 
  897 /*
  898  * Add input-actions for widgets that are overlooked (scrollbar and toolbar):
  899  *
  900  *  a) Sometimes the scrollbar passes through translations, sometimes it
  901  *     doesn't.  We add the KeyPress translations here, just to be sure.
  902  *  b) In the normal (non-toolbar) configuration, the xterm widget covers
  903  *     almost all of the window.  With a toolbar, there's a relatively
  904  *     large area that the user would expect to enter keystrokes since the
  905  *     program can get the focus.
  906  */
  907 void
  908 xtermAddInput(Widget w)
  909 {
  910     /* *INDENT-OFF* */
  911     XtActionsRec input_actions[] = {
  912     { "insert",         HandleKeyPressed }, /* alias */
  913     { "insert-eight-bit",       HandleEightBitKeyPressed },
  914     { "insert-seven-bit",       HandleKeyPressed },
  915     { "secure",         HandleSecure },
  916     { "string",         HandleStringEvent },
  917     { "scroll-back",        HandleScrollBack },
  918     { "scroll-forw",        HandleScrollForward },
  919     { "scroll-to",          HandleScrollTo },
  920     { "select-cursor-end",      HandleKeyboardSelectEnd },
  921     { "select-cursor-extend",   HandleKeyboardSelectExtend },
  922     { "select-cursor-start",    HandleKeyboardSelectStart },
  923     { "insert-selection",       HandleInsertSelection },
  924     { "select-start",       HandleSelectStart },
  925     { "select-extend",      HandleSelectExtend },
  926     { "start-extend",       HandleStartExtend },
  927     { "select-end",         HandleSelectEnd },
  928     { "clear-saved-lines",      HandleClearSavedLines },
  929     { "popup-menu",         HandlePopupMenu },
  930     { "bell",           HandleBell },
  931     { "ignore",         HandleIgnore },
  932 #if OPT_DABBREV
  933     { "dabbrev-expand",     HandleDabbrevExpand },
  934 #endif
  935 #if OPT_MAXIMIZE
  936     { "fullscreen",         HandleFullscreen },
  937 #endif
  938 #if OPT_SCROLL_LOCK
  939     { "scroll-lock",        HandleScrollLock },
  940 #endif
  941 #if OPT_SHIFT_FONTS
  942     { "larger-vt-font",     HandleLargerFont },
  943     { "smaller-vt-font",        HandleSmallerFont },
  944 #endif
  945     };
  946     /* *INDENT-ON* */
  947 
  948     TRACE_TRANS("BEFORE", w);
  949     XtAppAddActions(app_con, input_actions, XtNumber(input_actions));
  950     XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations));
  951     TRACE_TRANS("AFTER:", w);
  952 
  953 #if OPT_EXTRA_PASTE
  954     if (term && term->keyboard.extra_translations)
  955     XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations));
  956 #endif
  957 }
  958 
  959 #if OPT_ISO_COLORS
  960 #ifdef EXP_BOGUS_FG
  961 static Bool
  962 CheckBogusForeground(TScreen *screen, const char *tag)
  963 {
  964     int row = -1, col = -1, pass;
  965     Bool isClear = True;
  966 
  967     (void) tag;
  968     for (pass = 0; pass < 2; ++pass) {
  969     row = screen->cur_row;
  970     for (; isClear && (row <= screen->max_row); ++row) {
  971         CLineData *ld = getLineData(screen, row);
  972 
  973         if (ld != 0) {
  974         IAttr *attribs = ld->attribs;
  975 
  976         col = (row == screen->cur_row) ? screen->cur_col : 0;
  977         for (; isClear && (col <= screen->max_col); ++col) {
  978             unsigned flags = attribs[col];
  979             if (pass) {
  980             flags &= ~FG_COLOR;
  981             attribs[col] = (IAttr) flags;
  982             } else if ((flags & BG_COLOR)) {
  983             isClear = False;
  984             } else if ((flags & FG_COLOR)) {
  985             unsigned ch = ld->charData[col];
  986             isClear = ((ch == ' ') || (ch == 0));
  987             } else {
  988             isClear = False;
  989             }
  990         }
  991         }
  992     }
  993     }
  994     TRACE(("%s checked %d,%d to %d,%d %s pass %d\n",
  995        tag, screen->cur_row, screen->cur_col,
  996        row, col,
  997        isClear && pass ? "cleared" : "unchanged",
  998        pass));
  999 
 1000     return isClear;
 1001 }
 1002 #endif
 1003 
 1004 /*
 1005  * The terminal's foreground and background colors are set via two mechanisms:
 1006  *  text (cur_foreground, cur_background values that are passed down to
 1007  *      XDrawImageString and XDrawString)
 1008  *  area (X11 graphics context used in XClearArea and XFillRectangle)
 1009  */
 1010 void
 1011 SGR_Foreground(XtermWidget xw, int color)
 1012 {
 1013     TScreen *screen = TScreenOf(xw);
 1014     Pixel fg;
 1015 
 1016     if (color >= 0) {
 1017     UIntSet(xw->flags, FG_COLOR);
 1018     } else {
 1019     UIntClr(xw->flags, FG_COLOR);
 1020     }
 1021     fg = getXtermFG(xw, xw->flags, color);
 1022     xw->cur_foreground = color;
 1023 
 1024     setCgsFore(xw, WhichVWin(screen), gcNorm, fg);
 1025     setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg);
 1026 
 1027     setCgsFore(xw, WhichVWin(screen), gcBold, fg);
 1028     setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg);
 1029 
 1030 #ifdef EXP_BOGUS_FG
 1031     /*
 1032      * If we've just turned off the foreground color, check for blank cells
 1033      * which have no background color, but do have foreground color.  This
 1034      * could happen due to setting the foreground color just before scrolling.
 1035      *
 1036      * Those cells look uncolored, but will confuse ShowCursor(), which looks
 1037      * for the colors in the current cell, and will see the foreground color.
 1038      * In that case, remove the foreground color from the blank cells.
 1039      */
 1040     if (color < 0) {
 1041     CheckBogusForeground(screen, "SGR_Foreground");
 1042     }
 1043 #endif
 1044 }
 1045 
 1046 void
 1047 SGR_Background(XtermWidget xw, int color)
 1048 {
 1049     TScreen *screen = TScreenOf(xw);
 1050     Pixel bg;
 1051 
 1052     /*
 1053      * An indexing operation may have set screen->scroll_amt, which would
 1054      * normally result in calling FlushScroll() in WriteText().  However,
 1055      * if we're changing the background color now, then the new value
 1056      * should not apply to the pending blank lines.
 1057      */
 1058     if (screen->scroll_amt && (color != xw->cur_background))
 1059     FlushScroll(xw);
 1060 
 1061     if (color >= 0) {
 1062     UIntSet(xw->flags, BG_COLOR);
 1063     } else {
 1064     UIntClr(xw->flags, BG_COLOR);
 1065     }
 1066     bg = getXtermBG(xw, xw->flags, color);
 1067     xw->cur_background = color;
 1068 
 1069     setCgsBack(xw, WhichVWin(screen), gcNorm, bg);
 1070     setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg);
 1071 
 1072     setCgsBack(xw, WhichVWin(screen), gcBold, bg);
 1073     setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg);
 1074 }
 1075 
 1076 /* Invoked after updating bold/underline flags, computes the extended color
 1077  * index to use for foreground.  (See also 'extract_fg()').
 1078  */
 1079 static void
 1080 setExtendedFG(XtermWidget xw)
 1081 {
 1082     int fg = xw->sgr_foreground;
 1083 
 1084     if (TScreenOf(xw)->colorAttrMode
 1085     || (fg < 0)) {
 1086     fg = MapToColorMode(fg, TScreenOf(xw), xw->flags);
 1087     }
 1088 
 1089     /* This implements the IBM PC-style convention of 8-colors, with one
 1090      * bit for bold, thus mapping the 0-7 codes to 8-15.  It won't make
 1091      * much sense for 16-color applications, but we keep it to retain
 1092      * compatibility with ANSI-color applications.
 1093      */
 1094 #if OPT_PC_COLORS       /* XXXJTL should be settable at runtime (resource or OSC?) */
 1095     if (TScreenOf(xw)->boldColors
 1096     && (!xw->sgr_38_xcolors)
 1097     && (fg >= 0)
 1098     && (fg < 8)
 1099     && (xw->flags & BOLD))
 1100     fg |= 8;
 1101 #endif
 1102 
 1103     SGR_Foreground(xw, fg);
 1104 }
 1105 
 1106 /* Invoked after updating inverse flag, computes the extended color
 1107  * index to use for background.  (See also 'extract_bg()').
 1108  */
 1109 static void
 1110 setExtendedBG(XtermWidget xw)
 1111 {
 1112     int bg = xw->sgr_background;
 1113 
 1114     if (TScreenOf(xw)->colorAttrMode
 1115     || (bg < 0)) {
 1116     if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE))
 1117         bg = COLOR_RV;
 1118     }
 1119 
 1120     SGR_Background(xw, bg);
 1121 }
 1122 
 1123 void
 1124 setExtendedColors(XtermWidget xw)
 1125 {
 1126     setExtendedFG(xw);
 1127     setExtendedBG(xw);
 1128 }
 1129 
 1130 static void
 1131 reset_SGR_Foreground(XtermWidget xw)
 1132 {
 1133     xw->sgr_foreground = -1;
 1134     xw->sgr_38_xcolors = False;
 1135     clrDirectFG(xw->flags);
 1136     setExtendedFG(xw);
 1137 }
 1138 
 1139 static void
 1140 reset_SGR_Background(XtermWidget xw)
 1141 {
 1142     xw->sgr_background = -1;
 1143     clrDirectBG(xw->flags);
 1144     setExtendedBG(xw);
 1145 }
 1146 
 1147 static void
 1148 reset_SGR_Colors(XtermWidget xw)
 1149 {
 1150     reset_SGR_Foreground(xw);
 1151     reset_SGR_Background(xw);
 1152 }
 1153 #endif /* OPT_ISO_COLORS */
 1154 
 1155 #if OPT_WIDE_ATTRS
 1156 /*
 1157  * Call this before changing the state of ATR_ITALIC, to update the GC fonts.
 1158  */
 1159 static void
 1160 setItalicFont(XtermWidget xw, Bool enable)
 1161 {
 1162     if (enable) {
 1163     if ((xw->flags & ATR_ITALIC) == 0) {
 1164         xtermLoadItalics(xw);
 1165         TRACE(("setItalicFont: enabling Italics\n"));
 1166         xtermUpdateFontGCs(xw, getItalicFont);
 1167     }
 1168     } else if ((xw->flags & ATR_ITALIC) != 0) {
 1169     TRACE(("setItalicFont: disabling Italics\n"));
 1170     xtermUpdateFontGCs(xw, getNormalFont);
 1171     }
 1172 }
 1173 
 1174 static void
 1175 ResetItalics(XtermWidget xw)
 1176 {
 1177     setItalicFont(xw, False);
 1178     UIntClr(xw->flags, ATR_ITALIC);
 1179 }
 1180 
 1181 #else
 1182 #define ResetItalics(xw)    /* nothing */
 1183 #endif
 1184 
 1185 static void
 1186 initCharset(TScreen *screen, int which, DECNRCM_codes code)
 1187 {
 1188     screen->gsets[which] = code;
 1189 }
 1190 
 1191 void
 1192 saveCharsets(TScreen *screen, DECNRCM_codes * target)
 1193 {
 1194     int g;
 1195     for (g = 0; g < NUM_GSETS; ++g) {
 1196     target[g] = screen->gsets[g];
 1197     }
 1198 }
 1199 
 1200 void
 1201 restoreCharsets(TScreen *screen, DECNRCM_codes * source)
 1202 {
 1203     int g;
 1204     for (g = 0; g < NUM_GSETS; ++g) {
 1205     screen->gsets[g] = source[g];
 1206     }
 1207 }
 1208 
 1209 void
 1210 resetCharsets(TScreen *screen)
 1211 {
 1212     TRACE(("resetCharsets\n"));
 1213 
 1214     initCharset(screen, 0, nrc_ASCII);
 1215     initCharset(screen, 1, nrc_ASCII);
 1216     initCharset(screen, 2, nrc_ASCII);
 1217     initCharset(screen, 3, nrc_ASCII);
 1218 
 1219     screen->curgl = 0;      /* G0 => GL.            */
 1220     screen->curgr = 2;      /* G2 => GR.            */
 1221     screen->curss = 0;      /* No single shift.     */
 1222 
 1223 #if OPT_VT52_MODE
 1224     if (screen->vtXX_level == 0)
 1225     initCharset(screen, 1, nrc_DEC_Spec_Graphic);   /* Graphics */
 1226 #endif
 1227 }
 1228 
 1229 static void
 1230 modified_DECNRCM(XtermWidget xw)
 1231 {
 1232 #if OPT_WIDE_CHARS
 1233     TScreen *screen = TScreenOf(xw);
 1234     if (screen->wide_chars && (screen->utf8_mode || screen->utf8_nrc_mode)) {
 1235     int enabled = ((xw->flags & NATIONAL) != 0);
 1236     int modefix;
 1237     EXCHANGE(screen->utf8_nrc_mode, screen->utf8_mode, modefix);
 1238     switchPtyData(screen, !enabled);
 1239     TRACE(("UTF8 mode temporarily %s\n", enabled ? "ON" : "OFF"));
 1240     }
 1241 #else
 1242     (void) xw;
 1243 #endif
 1244 }
 1245 
 1246 /*
 1247  * VT300 and up support three ANSI conformance levels, defined according to
 1248  * the dpANSI X3.134.1 standard.  DEC's manuals equate levels 1 and 2, and
 1249  * are unclear.  This code is written based on the manuals.
 1250  */
 1251 static void
 1252 set_ansi_conformance(TScreen *screen, int level)
 1253 {
 1254     TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n",
 1255        level,
 1256        screen->vtXX_level * 100,
 1257        screen->terminal_id,
 1258        screen->ansi_level));
 1259     if (screen->vtXX_level >= 3) {
 1260     switch (screen->ansi_level = level) {
 1261     case 1:
 1262         /* FALLTHRU */
 1263     case 2:
 1264         initCharset(screen, 0, nrc_ASCII);  /* G0 is ASCII */
 1265         initCharset(screen, 1, nrc_ASCII);  /* G1 is ISO Latin-1 */
 1266         screen->curgl = 0;
 1267         screen->curgr = 1;
 1268         break;
 1269     case 3:
 1270         initCharset(screen, 0, nrc_ASCII);  /* G0 is ASCII */
 1271         screen->curgl = 0;
 1272         break;
 1273     }
 1274     }
 1275 }
 1276 
 1277 /*
 1278  * Set scrolling margins.  VTxxx terminals require that the top/bottom are
 1279  * different, so we have at least two lines in the scrolling region.
 1280  */
 1281 static void
 1282 set_tb_margins(TScreen *screen, int top, int bottom)
 1283 {
 1284     TRACE(("set_tb_margins %d..%d, prior %d..%d\n",
 1285        top, bottom,
 1286        screen->top_marg,
 1287        screen->bot_marg));
 1288     if (bottom > top) {
 1289     screen->top_marg = top;
 1290     screen->bot_marg = bottom;
 1291     }
 1292     if (screen->top_marg > screen->max_row)
 1293     screen->top_marg = screen->max_row;
 1294     if (screen->bot_marg > screen->max_row)
 1295     screen->bot_marg = screen->max_row;
 1296 }
 1297 
 1298 static void
 1299 set_lr_margins(TScreen *screen, int left, int right)
 1300 {
 1301     TRACE(("set_lr_margins %d..%d, prior %d..%d\n",
 1302        left, right,
 1303        screen->lft_marg,
 1304        screen->rgt_marg));
 1305     if (right > left) {
 1306     screen->lft_marg = left;
 1307     screen->rgt_marg = right;
 1308     }
 1309     if (screen->lft_marg > screen->max_col)
 1310     screen->lft_marg = screen->max_col;
 1311     if (screen->rgt_marg > screen->max_col)
 1312     screen->rgt_marg = screen->max_col;
 1313 }
 1314 
 1315 #define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row)
 1316 #define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col)
 1317 
 1318 void
 1319 resetMargins(XtermWidget xw)
 1320 {
 1321     TScreen *screen = TScreenOf(xw);
 1322 
 1323     UIntClr(xw->flags, LEFT_RIGHT);
 1324     reset_tb_margins(screen);
 1325     reset_lr_margins(screen);
 1326 }
 1327 
 1328 static void
 1329 resetRendition(XtermWidget xw)
 1330 {
 1331     TScreen *screen = TScreenOf(xw);
 1332     (void) screen;
 1333     ResetItalics(xw);
 1334     UIntClr(xw->flags,
 1335         (SGR_MASK | SGR_MASK2 | INVISIBLE));
 1336 }
 1337 
 1338 void
 1339 set_max_col(TScreen *screen, int cols)
 1340 {
 1341     TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col));
 1342     if (cols < 0)
 1343     cols = 0;
 1344     screen->max_col = cols;
 1345 }
 1346 
 1347 void
 1348 set_max_row(TScreen *screen, int rows)
 1349 {
 1350     TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row));
 1351     if (rows < 0)
 1352     rows = 0;
 1353     screen->max_row = rows;
 1354 }
 1355 
 1356 #if OPT_MOD_FKEYS
 1357 static void
 1358 set_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled)
 1359 {
 1360 #define SET_MOD_FKEYS(field) \
 1361     xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \
 1362                      ? xw->keyboard.modify_1st.field \
 1363                      : what; \
 1364     TRACE(("set modify_now.%s to %d\n", #field, \
 1365        xw->keyboard.modify_now.field));
 1366 
 1367     switch (which) {
 1368     case 0:
 1369     SET_MOD_FKEYS(allow_keys);
 1370     break;
 1371     case 1:
 1372     SET_MOD_FKEYS(cursor_keys);
 1373     break;
 1374     case 2:
 1375     SET_MOD_FKEYS(function_keys);
 1376     break;
 1377     case 3:
 1378     SET_MOD_FKEYS(keypad_keys);
 1379     break;
 1380     case 4:
 1381     SET_MOD_FKEYS(other_keys);
 1382     break;
 1383     case 5:
 1384     SET_MOD_FKEYS(string_keys);
 1385     break;
 1386     }
 1387 }
 1388 #endif /* OPT_MOD_FKEYS */
 1389 
 1390 #if OPT_TRACE
 1391 #define DATA(name) { name, #name }
 1392 static const struct {
 1393     Const PARSE_T *table;
 1394     const char *name;
 1395 } all_tables[] = {
 1396 
 1397     DATA(ansi_table)
 1398     ,DATA(cigtable)
 1399     ,DATA(csi2_table)
 1400     ,DATA(csi_ex_table)
 1401     ,DATA(csi_quo_table)
 1402     ,DATA(csi_table)
 1403     ,DATA(dec2_table)
 1404     ,DATA(dec3_table)
 1405     ,DATA(dec_table)
 1406     ,DATA(eigtable)
 1407     ,DATA(esc_sp_table)
 1408     ,DATA(esc_table)
 1409     ,DATA(scrtable)
 1410     ,DATA(scs96table)
 1411     ,DATA(scstable)
 1412     ,DATA(sos_table)
 1413 #if OPT_BLINK_CURS
 1414     ,DATA(csi_sp_table)
 1415 #endif
 1416 #if OPT_DEC_LOCATOR
 1417     ,DATA(csi_tick_table)
 1418 #endif
 1419 #if OPT_DEC_RECTOPS
 1420     ,DATA(csi_dollar_table)
 1421     ,DATA(csi_star_table)
 1422     ,DATA(csi_dec_dollar_table)
 1423 #endif
 1424 #if OPT_WIDE_CHARS
 1425     ,DATA(esc_pct_table)
 1426     ,DATA(scs_amp_table)
 1427     ,DATA(scs_pct_table)
 1428     ,DATA(scs_2qt_table)
 1429 #endif
 1430 #if OPT_VT52_MODE
 1431     ,DATA(vt52_table)
 1432     ,DATA(vt52_esc_table)
 1433     ,DATA(vt52_ignore_table)
 1434 #endif
 1435 #if OPT_XTERM_SGR
 1436     ,DATA(csi_hash_table)
 1437 #endif
 1438 #undef DATA
 1439 };
 1440 
 1441 #define WHICH_TABLE(name) if (table == name) result = #name
 1442 static const char *
 1443 which_table(Const PARSE_T * table)
 1444 {
 1445     const char *result = "?";
 1446     Cardinal n;
 1447     for (n = 0; n < XtNumber(all_tables); ++n) {
 1448     if (table == all_tables[n].table) {
 1449         result = all_tables[n].name;
 1450         break;
 1451     }
 1452     }
 1453 
 1454     return result;
 1455 }
 1456 
 1457 static void
 1458 check_tables(void)
 1459 {
 1460     Cardinal n;
 1461     int ch;
 1462     int total_codes = 0;
 1463     int total_ground = 0;
 1464     int total_ignored = 0;
 1465 
 1466     TRACE(("** check_tables\n"));
 1467     for (n = 0; n < XtNumber(all_tables); ++n) {
 1468     Const PARSE_T *table = all_tables[n].table;
 1469     TRACE(("*** %s\n", all_tables[n].name));
 1470     /*
 1471      * Most of the tables should use the same codes in 0..31, 128..159
 1472      * as the "ansi" table.
 1473      */
 1474     if (strncmp(all_tables[n].name, "ansi", 4) &&
 1475         strncmp(all_tables[n].name, "sos_", 4) &&
 1476         strncmp(all_tables[n].name, "vt52", 4)) {
 1477         for (ch = 0; ch < 32; ++ch) {
 1478         int c1 = ch + 128;
 1479         PARSE_T st_l = table[ch];
 1480         PARSE_T st_r = table[c1];
 1481         if (st_l != ansi_table[ch]) {
 1482             TRACE(("  %3d: %d vs %d\n", ch, st_l, ansi_table[ch]));
 1483         }
 1484         if (st_r != ansi_table[c1]) {
 1485             TRACE(("  %3d: %d vs %d\n", c1, st_r, ansi_table[c1]));
 1486         }
 1487         }
 1488     }
 1489     /*
 1490      * All of the tables should have their GL/GR parts encoded the same.
 1491      */
 1492     for (ch = 32; ch < 127; ++ch) {
 1493         PARSE_T st_l = table[ch];
 1494         PARSE_T st_r = table[ch + 128];
 1495         if (st_l != st_r) {
 1496         if (st_r == CASE_IGNORE &&
 1497             !strncmp(all_tables[n].name, "vt52", 4)) {
 1498             ;
 1499         } else {
 1500             TRACE(("  %3d: %d vs %d\n", ch, st_l, st_r));
 1501         }
 1502         }
 1503     }
 1504     /*
 1505      * Just for amusement, show how sparse the encoding tables are.
 1506      */
 1507     for (ch = 0; ch < 256; ++ch) {
 1508         ++total_codes;
 1509         switch (table[ch]) {
 1510         case CASE_GROUND_STATE:
 1511         total_ground++;
 1512         break;
 1513         case CASE_ESC_IGNORE:
 1514         /* FALLTHRU */
 1515         case CASE_IGNORE:
 1516         /* FALLTHRU */
 1517         case CASE_VT52_IGNORE:
 1518         total_ignored++;
 1519         break;
 1520         }
 1521     }
 1522     }
 1523     TRACE(("VTPrsTbl:\n"));
 1524     TRACE(("%d total codes\n", total_codes));
 1525     TRACE(("%d total ignored\n", total_ignored));
 1526     TRACE(("%d total reset/ground\n", total_ground));
 1527 }
 1528 
 1529 static void
 1530 check_bitmasks(void)
 1531 {
 1532 #define dMSK 0x100
 1533 #define DATA(mode,name) { mode, name, #name }
 1534 #define DMSK(what) (dMSK | (what))
 1535 #define DGRP(offs) (1 << ((offs) - 1))
 1536     static struct {
 1537     int mode;
 1538     int code;
 1539     Const char *name;
 1540     } table[] = {
 1541     DATA(DGRP(1), INVERSE),
 1542         DATA(DGRP(1), UNDERLINE),
 1543         DATA(DGRP(1), BOLD),
 1544         DATA(DGRP(1), BLINK),
 1545         DATA(DMSK(DGRP(1)), SGR_MASK),
 1546         DATA(DGRP(2), BG_COLOR),
 1547         DATA(DGRP(2), FG_COLOR),
 1548         DATA(DGRP(2), PROTECTED),
 1549         DATA(DGRP(4), CHARDRAWN),
 1550 #if OPT_WIDE_ATTRS
 1551         DATA(DGRP(2), ATR_FAINT),
 1552         DATA(DGRP(2), ATR_ITALIC),
 1553         DATA(DGRP(2), ATR_STRIKEOUT),
 1554         DATA(DGRP(2), ATR_DBL_UNDER),
 1555         DATA(DGRP(2), ATR_DIRECT_FG),
 1556         DATA(DGRP(2), ATR_DIRECT_BG),
 1557 #endif
 1558         DATA(DMSK(DGRP(2)), SGR_MASK2),
 1559         DATA(DGRP(3), WRAPAROUND),
 1560         DATA(DGRP(3), REVERSEWRAP),
 1561         DATA(DGRP(3), REVERSE_VIDEO),
 1562         DATA(DGRP(3), LINEFEED),
 1563         DATA(DGRP(3), ORIGIN),
 1564         DATA(DGRP(3), INSERT),
 1565         DATA(DGRP(3), SMOOTHSCROLL),
 1566         DATA(DGRP(3), IN132COLUMNS),
 1567         DATA(DGRP(3), INVISIBLE),
 1568         DATA(DMSK(DGRP(3)), ATTRIBUTES),
 1569         DATA(DGRP(5), NATIONAL),
 1570         DATA(DGRP(5), LEFT_RIGHT),
 1571         DATA(DGRP(5), NOCLEAR_COLM),
 1572         DATA(DGRP(4), NOBACKGROUND),
 1573         DATA(DGRP(4), NOTRANSLATION),
 1574         DATA(DGRP(4), DOUBLEWFONT),
 1575         DATA(DGRP(4), DOUBLEHFONT),
 1576         DATA(DGRP(4), CHARBYCHAR),
 1577         DATA(DGRP(4), NORESOLUTION),
 1578         DATA(DMSK(DGRP(1) | DGRP(2) | DGRP(4)), DRAWX_MASK),
 1579         DATA(-1, EOF)
 1580     };
 1581 #undef DATA
 1582     int j, k;
 1583     TRACE(("** check_bitmasks:\n"));
 1584     for (j = 0; table[j].mode >= 0; ++j) {
 1585     TRACE(("%4X %8X %s\n", table[j].mode, table[j].code, table[j].name));
 1586     if (table[j].mode & dMSK) {
 1587         int mask = dMSK;
 1588         for (k = 0; table[k].mode >= 0; ++k) {
 1589         if (j == k)
 1590             continue;
 1591         if (table[k].mode & dMSK)
 1592             continue;
 1593         if ((table[j].mode & table[k].mode) != 0)
 1594             mask |= table[k].mode;
 1595         }
 1596         if (mask != table[j].mode) {
 1597         TRACE(("...expected %08X\n", mask));
 1598         }
 1599     } else {
 1600         for (k = 0; table[k].mode >= 0; ++k) {
 1601         if (j == k)
 1602             continue;
 1603         if (table[k].mode & dMSK)
 1604             continue;
 1605         if ((table[j].code & table[k].code) != 0) {
 1606             TRACE(("...same bits %s\n", table[k].name));
 1607         }
 1608         }
 1609     }
 1610     }
 1611 }
 1612 #endif
 1613 
 1614 static int
 1615 init_params(void)
 1616 {
 1617     while (parms.count-- > 0) {
 1618     parms.is_sub[parms.count] = 0;
 1619     parms.params[parms.count] = 0;
 1620     }
 1621     parms.count = 0;
 1622     parms.has_subparams = 0;
 1623     return 0;
 1624 }
 1625 
 1626 #if OPT_TRACE > 0
 1627 static void
 1628 dump_params(void)
 1629 {
 1630     int n;
 1631     int arg;
 1632     TRACE(("params %d (%d)\n", nparam, parms.has_subparams));
 1633     for (arg = 1, n = 0; n < nparam; ++n) {
 1634     TRACE(("%3d.%d %d\n", arg, parms.is_sub[n], parms.params[n]));
 1635     if (!parms.is_sub[n])
 1636         ++arg;
 1637     }
 1638 }
 1639 #define DumpParams() dump_params()
 1640 #else
 1641 #define DumpParams()        /* nothing */
 1642 #endif
 1643 
 1644     /* allocate larger buffer if needed/possible */
 1645 #define SafeAlloc(type, area, used, size) \
 1646         type *new_string = area; \
 1647         size_t new_length = size; \
 1648         if (new_length == 0) { \
 1649             new_length = 1024; \
 1650             new_string = TypeMallocN(type, new_length); \
 1651         } else if (used+1 >= new_length) { \
 1652             new_length = size * 2; \
 1653             new_string = TypeMallocN(type, new_length); \
 1654             if (new_string != 0 \
 1655              && area != 0 \
 1656              && used != 0) { \
 1657             memcpy(new_string, area, used * sizeof(type)); \
 1658              } \
 1659         }
 1660 #define SafeFree(area, size) \
 1661         if (area != new_string) { \
 1662             free(area); \
 1663             area = new_string; \
 1664         } \
 1665         size = new_length
 1666 
 1667 #define WriteNow() {                        \
 1668         unsigned single = 0;                \
 1669                                 \
 1670         if (screen->curss) {                \
 1671         dotext(xw,                  \
 1672                screen->gsets[(int) (screen->curss)],    \
 1673                sp->print_area,              \
 1674                (Cardinal) 1);               \
 1675         screen->curss = 0;              \
 1676         single++;                   \
 1677         }                           \
 1678         if (sp->print_used > single) {          \
 1679         dotext(xw,                  \
 1680                screen->gsets[(int) (screen->curgl)],    \
 1681                sp->print_area + single,         \
 1682                (Cardinal) (sp->print_used - single));   \
 1683         }                           \
 1684         sp->print_used = 0;                 \
 1685     }                           \
 1686 
 1687 #define PARSE_SRM 1
 1688 
 1689 struct ParseState {
 1690     unsigned check_recur;
 1691 #if OPT_VT52_MODE
 1692     Bool vt52_cup;
 1693 #endif
 1694     Const PARSE_T *groundtable;
 1695     Const PARSE_T *parsestate;
 1696     int scstype;
 1697     int scssize;
 1698     Bool private_function;  /* distinguish private-mode from standard */
 1699     int string_mode;        /* nonzero iff we're processing a string */
 1700     int lastchar;       /* positive iff we had a graphic character */
 1701     int nextstate;
 1702 #if OPT_WIDE_CHARS
 1703     int last_was_wide;
 1704 #endif
 1705     /* Buffer for processing printable text */
 1706     IChar *print_area;
 1707     size_t print_size;
 1708     size_t print_used;
 1709     /* Buffer for processing strings (e.g., OSC ... ST) */
 1710     Char *string_area;
 1711     size_t string_size;
 1712     size_t string_used;
 1713     /* Buffer for deferring input */
 1714     Char *defer_area;
 1715     size_t defer_size;
 1716     size_t defer_used;
 1717 };
 1718 
 1719 static struct ParseState myState;
 1720 
 1721 static void
 1722 init_groundtable(TScreen *screen, struct ParseState *sp)
 1723 {
 1724     (void) screen;
 1725 
 1726 #if OPT_VT52_MODE
 1727     if (!(screen->vtXX_level)) {
 1728     sp->groundtable = vt52_table;
 1729     } else if (screen->terminal_id >= 100)
 1730 #endif
 1731     {
 1732     sp->groundtable = ansi_table;
 1733     }
 1734 }
 1735 
 1736 static void
 1737 select_charset(struct ParseState *sp, int type, int size)
 1738 {
 1739     TRACE(("select_charset %d %d\n", type, size));
 1740     sp->scstype = type;
 1741     sp->scssize = size;
 1742     if (size == 94) {
 1743     sp->parsestate = scstable;
 1744     } else {
 1745     sp->parsestate = scs96table;
 1746     }
 1747 }
 1748 /* *INDENT-OFF* */
 1749 static struct {
 1750     DECNRCM_codes result;
 1751     int prefix;
 1752     int suffix;
 1753     int min_level;
 1754     int max_level;
 1755     int need_nrc;
 1756 } scs_table[] = {
 1757     { nrc_ASCII,             0,   'B', 1, 9, 0 },
 1758     { nrc_British,           0,   'A', 1, 9, 0 },
 1759     { nrc_DEC_Spec_Graphic,  0,   '0', 1, 9, 0 },
 1760     { nrc_DEC_Alt_Chars,     0,   '1', 1, 1, 0 },
 1761     { nrc_DEC_Alt_Graphics,  0,   '2', 1, 1, 0 },
 1762     /* VT2xx */
 1763     { nrc_DEC_Supp,          0,   '<', 2, 9, 0 },
 1764     { nrc_Dutch,             0,   '4', 2, 9, 1 },
 1765     { nrc_Finnish,           0,   '5', 2, 9, 1 },
 1766     { nrc_Finnish2,          0,   'C', 2, 9, 1 },
 1767     { nrc_French,            0,   'R', 2, 9, 1 },
 1768     { nrc_French2,           0,   'f', 2, 9, 1 },
 1769     { nrc_French_Canadian,   0,   'Q', 2, 9, 1 },
 1770     { nrc_German,            0,   'K', 2, 9, 1 },
 1771     { nrc_Italian,           0,   'Y', 2, 9, 1 },
 1772     { nrc_Norwegian_Danish2, 0,   'E', 2, 9, 1 },
 1773     { nrc_Norwegian_Danish3, 0,   '6', 2, 9, 1 },
 1774     { nrc_Spanish,           0,   'Z', 2, 9, 1 },
 1775     { nrc_Swedish,           0,   '7', 2, 9, 1 },
 1776     { nrc_Swedish2,          0,   'H', 2, 9, 1 },
 1777     { nrc_Swiss,             0,   '=', 2, 9, 1 },
 1778     /* VT3xx */
 1779     { nrc_British_Latin_1,   0,   'A', 3, 9, 1 },
 1780     { nrc_DEC_Supp_Graphic,  '%', '5', 3, 9, 0 },
 1781     { nrc_DEC_Technical,     0,   '>', 3, 9, 0 },
 1782     { nrc_French_Canadian2,  0,   '9', 3, 9, 1 },
 1783     { nrc_Norwegian_Danish,  0,   '`', 3, 9, 1 },
 1784     { nrc_Portugese,         '%', '6', 3, 9, 1 },
 1785     /* VT5xx */
 1786     { nrc_Cyrillic,          '&', '4', 5, 9, 1 },
 1787     { nrc_Greek,             '"', '>', 5, 9, 1 },
 1788     { nrc_Hebrew,            '%', '=', 5, 9, 1 },
 1789     { nrc_Turkish,       '%', '2', 5, 9, 1 },
 1790     { nrc_DEC_Greek_Supp,    '"', '?', 5, 9, 0 },
 1791     { nrc_DEC_Hebrew_Supp,   '"', '4', 5, 9, 0 },
 1792     { nrc_DEC_Turkish_Supp,  '%', '0', 5, 9, 0 },
 1793     { nrc_ISO_Greek_Supp,    0,   'F', 5, 9, 0 },
 1794     { nrc_ISO_Hebrew_Supp,   0,   'H', 5, 9, 0 },
 1795     { nrc_ISO_Latin_5_Supp,  0,   'M', 5, 9, 0 },
 1796     { nrc_ISO_Latin_Cyrillic,0,   'L', 5, 9, 0 },
 1797     /* VT5xx (not implemented) */
 1798 #if 0
 1799     { nrc_Russian,           '&', '5', 5, 9, 1 },
 1800     { nrc_SCS_NRCS,          '%', '3', 5, 9, 0 },
 1801 #endif
 1802 };
 1803 /* *INDENT-ON* */
 1804 
 1805 #if OPT_DEC_RECTOPS
 1806 static char *
 1807 encode_scs(DECNRCM_codes value)
 1808 {
 1809     static char buffer[3];
 1810     Cardinal n;
 1811     char *result = buffer;
 1812     for (n = 0; n < XtNumber(scs_table); ++n) {
 1813     if (scs_table[n].result == value) {
 1814         if (scs_table[n].prefix)
 1815         *result++ = (char) scs_table[n].prefix;
 1816         if (scs_table[n].suffix)
 1817         *result++ = (char) scs_table[n].suffix;
 1818         break;
 1819     }
 1820     }
 1821     *result = '\0';
 1822     return buffer;
 1823 }
 1824 #endif
 1825 
 1826 void
 1827 xtermDecodeSCS(XtermWidget xw, int which, int prefix, int suffix)
 1828 {
 1829     TScreen *screen = TScreenOf(xw);
 1830     Cardinal n;
 1831     DECNRCM_codes result = nrc_Unknown;
 1832 
 1833     suffix &= 0x7f;
 1834     for (n = 0; n < XtNumber(scs_table); ++n) {
 1835     if (prefix == scs_table[n].prefix
 1836         && suffix == scs_table[n].suffix
 1837         && screen->vtXX_level >= scs_table[n].min_level
 1838         && screen->vtXX_level <= scs_table[n].max_level
 1839         && (scs_table[n].need_nrc == 0 || (xw->flags & NATIONAL) != 0)) {
 1840         result = scs_table[n].result;
 1841         break;
 1842     }
 1843     }
 1844     if (result != nrc_Unknown) {
 1845     initCharset(screen, which, result);
 1846     TRACE(("setting G%d to %s\n", which, visibleScsCode((int) result)));
 1847     } else {
 1848     TRACE(("...unknown GSET\n"));
 1849     }
 1850 }
 1851 
 1852 /*
 1853  * Given a parameter number, and subparameter (starting in each case from zero)
 1854  * return the corresponding index into the parameter array.  If the combination
 1855  * is not found, return -1.
 1856  */
 1857 static int
 1858 subparam_index(int p, int s)
 1859 {
 1860     int result = -1;
 1861     int j, p2, s2;
 1862 
 1863     for (j = p2 = 0; j < nparam; ++j, ++p2) {
 1864     if (parms.is_sub[j]) {
 1865         s2 = 0;
 1866 
 1867         do {
 1868         if ((p == p2) && (s == s2)) {
 1869             result = j;
 1870             break;
 1871         }
 1872         ++s2;
 1873         } while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j]));
 1874 
 1875         if (result >= 0)
 1876         break;
 1877 
 1878         --j;        /* undo the last "while" */
 1879     } else if (p == p2) {
 1880         if (s == 0) {
 1881         result = j;
 1882         }
 1883         break;
 1884     }
 1885     }
 1886     TRACE2(("...subparam_index %d.%d = %d\n", p + 1, s + 1, result));
 1887     return result;
 1888 }
 1889 
 1890 /*
 1891  * Check if the given item in the parameter array has subparameters.
 1892  * If so, return the number of subparameters to use as a loop limit, etc.
 1893  */
 1894 static int
 1895 param_has_subparams(int item)
 1896 {
 1897     int result = 0;
 1898     if (parms.has_subparams) {
 1899     int n = subparam_index(item, 0);
 1900     if (n >= 0 && parms.is_sub[n]) {
 1901         while (++n < nparam && parms.is_sub[n - 1] < parms.is_sub[n]) {
 1902         result++;
 1903         }
 1904     }
 1905     }
 1906     TRACE(("...param_has_subparams(%d) ->%d\n", item, result));
 1907     return result;
 1908 }
 1909 
 1910 #if OPT_DIRECT_COLOR || OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS
 1911 /*
 1912  * Given an index into the parameter array, return the corresponding parameter
 1913  * number (starting from zero).
 1914  */
 1915 static int
 1916 param_number(int item)
 1917 {
 1918     int result = -1;
 1919     int j, p;
 1920 
 1921     for (j = p = 0; j < nparam; ++j, ++p) {
 1922     if (p >= item) {
 1923         result = j;
 1924         break;
 1925     }
 1926     if (parms.is_sub[j]) {
 1927         while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])) {
 1928         /* EMPTY */
 1929         }
 1930         --j;
 1931     }
 1932     }
 1933 
 1934     TRACE2(("...param_number(%d) = %d\n", item, result));
 1935     return result;
 1936 }
 1937 
 1938 static int
 1939 get_subparam(int p, int s)
 1940 {
 1941     int item = subparam_index(p, s);
 1942     int result = (item >= 0) ? parms.params[item] : DEFAULT;
 1943     TRACE(("...get_subparam[%d] = %d\n", item, result));
 1944     return result;
 1945 }
 1946 
 1947 /*
 1948  * Some background -
 1949  *
 1950  * Todd Larason provided the initial changes to support 256-colors in July 1999.
 1951  * I pointed out that the description of SGR 38/48 in ECMA-48 was vague, and
 1952  * was unsure if there would be some standard using those codes.  His response
 1953  * was that this was documented (it turns out, in equally vague terms) in ITU
 1954  * T.416
 1955  *
 1956  * Discussing this with Todd Larason in mid-1999, my point was that given the
 1957  * high cost of obtaining ITU T.416 (ISO-8613-6), the standard was not going
 1958  * to be effective (more than $100 then, more than $200 in 2012)
 1959  *
 1960  * We overlooked the detail about ":" as a subparameter delimiter (documented
 1961  * in 5.4.2 in ECMA-48).  Some discussion in KDE in mid-2006 led Lars Doelle
 1962  * to discuss the issue with me.  Lars' initial concern dealt with the fact
 1963  * that a sequence such as
 1964  *  CSI 38 ; 5 ; 1 m
 1965  * violated the principle that SGR parameters could be used in any order.
 1966  * Further discussion (see KDE #107487) resolved that the standard expected
 1967  * that the sequence would look like
 1968  *  CSI 38 ; 5 : 1 m
 1969  * which still violates that principle, since the "5:1" parameter has to
 1970  * follow the "38" to be useful.
 1971  *
 1972  * This function accepts either format (per request by Paul Leonerd Evans).
 1973  * It also accepts
 1974  *  CSI 38 : 5 : 1 m
 1975  * according to Lars' original assumption.  While implementing that, I added
 1976  * support for Konsole's interpretation of "CSI 38 : 2" as a 24-bit RGB value.
 1977  * ISO-8613-6 documents that as "direct color".
 1978  *
 1979  * At the time in 2012, no one noticed (or commented) regarding ISO-8613-6's
 1980  * quirk in the description of direct color:  it mentions a color space
 1981  * identifier parameter which should follow the "2" (as parameter 1).  In the
 1982  * same section, ISO-8613-6 mentions a parameter 6 which can be ignored, as
 1983  * well as parameters 7 and 8.  Like parameter 1, parameters 7 and 8 are not
 1984  * defined clearly in the standard, and a close reading indicates they are
 1985  * optional, saying they "may be used".  This implementation ignores parameters
 1986  * 6 (and above), and provides for the color space identifier by checking the
 1987  * number of parameters:
 1988  *  3 after "2" (no color space identifier)
 1989  *  4 or more after "2" (color space identifier)
 1990  *
 1991  * By the way - all of the parameters are decimal integers, and missing
 1992  * parameters represent a default value.  ISO-8613-6 is clear about that.
 1993  *
 1994  * Aside from ISO-8613-3, there is no standard use of ":" as a delimiter.
 1995  * ECMA-48 says only:
 1996  *
 1997  *  5.4.2 Parameter string format
 1998  *
 1999  *  A parameter string which does not start with a bit combination in the
 2000  *  range 03/12 to 03/15 shall have the following format:
 2001  *
 2002  *      a) A parameter string consists of one or more parameter
 2003  *         sub-strings, each of which represents a number in decimal
 2004  *         notation.
 2005  *
 2006  *      b) Each parameter sub-string consists of one or more bit
 2007  *         combinations from 03/00 to 03/10; the bit combinations from
 2008  *         03/00 to 03/09 represent the digits ZERO to NINE; bit
 2009  *         combination 03/10 may be used as a separator in a parameter
 2010  *         sub-string, for example, to separate the fractional part of a
 2011  *         decimal number from the integer part of that number.
 2012  *
 2013  * That is, there is no mention in ECMA-48 of the possibility that a parameter
 2014  * string might be a list of parameters, as done in ISO-8613-3 (nor does
 2015  * ECMA-48 provide an example where the ":" separator might be used).  Because
 2016  * of this, xterm treats other cases than those needed for ISO-8613-3 as an
 2017  * error, and stops interpreting the sequence.
 2018  */
 2019 #define extended_colors_limit(n) ((n) == 5 ? 1 : ((n) == 2 ? 3 : 0))
 2020 static Boolean
 2021 parse_extended_colors(XtermWidget xw, int *colorp, int *itemp, Boolean *extended)
 2022 {
 2023     Boolean result = False;
 2024     int item = *itemp;
 2025     int next = item;
 2026     int base = param_number(item);
 2027     int code = -1;
 2028     int values[3];      /* maximum number of subparameters */
 2029     int need = 0;       /* number of subparameters needed */
 2030     int have;
 2031     int n;
 2032 
 2033     /*
 2034      * On entry, 'item' points to the 38/48 code in the parameter array.
 2035      * If that has subparameters, we will expect all of the values to
 2036      * be subparameters of that item.
 2037      */
 2038     if ((have = param_has_subparams(item)) != 0) {
 2039     /* accept CSI 38 : 5 : 1 m */
 2040     /* accept CSI 38 : 2 : 1 : 2 : 3 m */
 2041     code = get_subparam(base, 1);
 2042     need = extended_colors_limit(code);
 2043     next = item + have;
 2044     for (n = 0; n < need && n < 3; ++n) {
 2045         values[n] = get_subparam(base, 2 + n + (have > 4));
 2046     }
 2047     } else if (++item < nparam) {
 2048     ++base;
 2049     if ((have = param_has_subparams(item)) != 0) {
 2050         /* accept CSI 38 ; 5 : 1 m */
 2051         /* accept CSI 38 ; 2 : 1 : 2 : 3 m */
 2052         code = get_subparam(base, 0);
 2053         need = extended_colors_limit(code);
 2054         next = base + have;
 2055         for (n = 0; n < need && n < 3; ++n) {
 2056         values[n] = get_subparam(base, 1 + n + (have > 3));
 2057         }
 2058     } else {
 2059         /* accept CSI 38 ; 5 ; 1 m */
 2060         /* accept CSI 38 ; 2 ; 1 ; 2 ; 3 m */
 2061         code = GetParam(item);
 2062         need = extended_colors_limit(code);
 2063         next = item + need;
 2064         for (n = 0; n < need && n < 3; ++n) {
 2065         values[n] = GetParam(item + 1 + n);
 2066         }
 2067     }
 2068     }
 2069     item = next;
 2070 
 2071     *extended = False;
 2072     switch (code) {
 2073     case 2:
 2074     /* direct color in rgb space */
 2075     if ((values[0] >= 0 && values[0] < 256) &&
 2076         (values[1] >= 0 && values[1] < 256) &&
 2077         (values[2] >= 0 && values[2] < 256)) {
 2078 #if OPT_DIRECT_COLOR
 2079         if (TScreenOf(xw)->direct_color && xw->has_rgb) {
 2080         *colorp = getDirectColor(xw, values[0], values[1], values[2]);
 2081         result = True;
 2082         *extended = True;
 2083         } else
 2084 #endif
 2085         {
 2086         *colorp = xtermClosestColor(xw, values[0], values[1], values[2]);
 2087         result = okIndexedColor(*colorp);
 2088         }
 2089     } else {
 2090         *colorp = -1;
 2091     }
 2092     break;
 2093     case 5:
 2094     /* indexed color */
 2095     *colorp = values[0];
 2096     result = okIndexedColor(*colorp);
 2097     break;
 2098     default:
 2099     *colorp = -1;
 2100     break;
 2101     }
 2102 
 2103     TRACE(("...resulting color %d/%d %s\n",
 2104        *colorp, NUM_ANSI_COLORS,
 2105        result ? "OK" : "ERR"));
 2106 
 2107     *itemp = item;
 2108     return result;
 2109 }
 2110 #endif /* ...extended_colors */
 2111 
 2112 static int
 2113 optional_param(int which)
 2114 {
 2115     return (nparam > which) ? GetParam(which) : DEFAULT;
 2116 }
 2117 
 2118 static int
 2119 zero_if_default(int which)
 2120 {
 2121     int result = (nparam > which) ? GetParam(which) : 0;
 2122     if (result <= 0)
 2123     result = 0;
 2124     return result;
 2125 }
 2126 
 2127 static int
 2128 one_if_default(int which)
 2129 {
 2130     int result = (nparam > which) ? GetParam(which) : 0;
 2131     if (result <= 0)
 2132     result = 1;
 2133     return result;
 2134 }
 2135 
 2136 /*
 2137  * Color palette changes using the OSC controls require a repaint of the
 2138  * screen - but not immediately.  Do the repaint as soon as we detect a
 2139  * state which will not lead to another color palette change.
 2140  */
 2141 static void
 2142 repaintWhenPaletteChanged(XtermWidget xw, struct ParseState *sp)
 2143 {
 2144     Boolean ignore = False;
 2145 
 2146     switch (sp->nextstate) {
 2147     case CASE_ESC:
 2148     ignore = ((sp->parsestate == ansi_table) ||
 2149           (sp->parsestate == sos_table));
 2150     break;
 2151     case CASE_OSC:
 2152     ignore = ((sp->parsestate == ansi_table) ||
 2153           (sp->parsestate == esc_table));
 2154     break;
 2155     case CASE_IGNORE:
 2156     ignore = (sp->parsestate == sos_table);
 2157     break;
 2158     case CASE_ST:
 2159     ignore = ((sp->parsestate == esc_table) ||
 2160           (sp->parsestate == sos_table));
 2161     break;
 2162     case CASE_ESC_DIGIT:
 2163     ignore = (sp->parsestate == csi_table);
 2164     break;
 2165     case CASE_ESC_SEMI:
 2166     ignore = (sp->parsestate == csi2_table);
 2167     break;
 2168     }
 2169 
 2170     if (!ignore) {
 2171     TRACE(("repaintWhenPaletteChanged\n"));
 2172     xw->work.palette_changed = False;
 2173     xtermRepaint(xw);
 2174     }
 2175 }
 2176 
 2177 #if OPT_C1_PRINT || OPT_WIDE_CHARS
 2178 #define ParseSOS(screen) ((screen)->c1_printable == 0)
 2179 #else
 2180 #define ParseSOS(screen) 0
 2181 #endif
 2182 
 2183 #define ResetState(sp) InitParams(), (sp)->parsestate = (sp)->groundtable
 2184 
 2185 static void
 2186 illegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp)
 2187 {
 2188     ResetState(sp);
 2189     sp->nextstate = sp->parsestate[E2A(c)];
 2190     Bell(xw, XkbBI_MinorError, 0);
 2191 }
 2192 
 2193 static void
 2194 init_parser(XtermWidget xw, struct ParseState *sp)
 2195 {
 2196     TScreen *screen = TScreenOf(xw);
 2197 
 2198     memset(sp, 0, sizeof(*sp));
 2199     sp->scssize = 94;       /* number of printable/nonspace ASCII */
 2200     sp->lastchar = -1;      /* not a legal IChar */
 2201     sp->nextstate = -1;     /* not a legal state */
 2202 
 2203     init_groundtable(screen, sp);
 2204     ResetState(sp);
 2205 }
 2206 
 2207 static void
 2208 init_reply(unsigned type)
 2209 {
 2210     memset(&reply, 0, sizeof(reply));
 2211     reply.a_type = (Char) type;
 2212 }
 2213 
 2214 static void
 2215 deferparsing(unsigned c, struct ParseState *sp)
 2216 {
 2217     SafeAlloc(Char, sp->defer_area, sp->defer_used, sp->defer_size);
 2218     if (new_string == 0) {
 2219     xtermWarning("Cannot allocate %lu bytes for deferred parsing of %u\n",
 2220              (unsigned long) new_length, c);
 2221     return;
 2222     }
 2223     SafeFree(sp->defer_area, sp->defer_size);
 2224     sp->defer_area[(sp->defer_used)++] = CharOf(c);
 2225 }
 2226 
 2227 #if OPT_VT52_MODE
 2228 static void
 2229 update_vt52_vt100_settings(void)
 2230 {
 2231     update_autowrap();
 2232     update_reversewrap();
 2233     update_autolinefeed();
 2234     update_appcursor();
 2235     update_appkeypad();
 2236     update_allow132();
 2237 }
 2238 #endif
 2239 
 2240 static Boolean
 2241 doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
 2242 {
 2243     TScreen *screen = TScreenOf(xw);
 2244     int item;
 2245     int count;
 2246     int value;
 2247     int laststate;
 2248     int thischar = -1;
 2249     XTermRect myRect;
 2250 #if OPT_DEC_RECTOPS
 2251     int thispage = 1;
 2252 #endif
 2253 
 2254     if (sp->check_recur) {
 2255     /* Defer parsing when parser is already running as the parser is not
 2256      * safe to reenter.
 2257      */
 2258     deferparsing(c, sp);
 2259     return True;
 2260     }
 2261 
 2262     do {
 2263 #if OPT_WIDE_CHARS
 2264     int this_is_wide = 0;
 2265 
 2266     /*
 2267      * Handle zero-width combining characters.  Make it faster by noting
 2268      * that according to the Unicode charts, the majority of Western
 2269      * character sets do not use this feature.  There are some unassigned
 2270      * codes at 0x242, but no zero-width characters until past 0x300.
 2271      */
 2272     if (c >= 0x300
 2273         && screen->wide_chars
 2274         && CharWidth(c) == 0
 2275         && !isWideControl(c)) {
 2276         int prev, test;
 2277         Boolean used = True;
 2278         int use_row;
 2279         int use_col;
 2280 
 2281         WriteNow();
 2282         use_row = (screen->char_was_written
 2283                ? screen->last_written_row
 2284                : screen->cur_row);
 2285         use_col = (screen->char_was_written
 2286                ? screen->last_written_col
 2287                : screen->cur_col);
 2288 
 2289         /*
 2290          * Check if the latest data can be added to the base character.
 2291          * If there is already a combining character stored for the cell,
 2292          * we cannot, since that would change the order.
 2293          */
 2294         if (screen->normalized_c
 2295         && !IsCellCombined(screen, use_row, use_col)) {
 2296         prev = (int) XTERM_CELL(use_row, use_col);
 2297         test = do_precomposition(prev, (int) c);
 2298         TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n",
 2299                prev, CharWidth(prev),
 2300                (int) c, CharWidth(c),
 2301                test, CharWidth(test)));
 2302         } else {
 2303         prev = -1;
 2304         test = -1;
 2305         }
 2306 
 2307         /* substitute combined character with precomposed character
 2308          * only if it does not change the width of the base character
 2309          */
 2310         if (test != -1
 2311         && CharWidth(test) == CharWidth(prev)) {
 2312         putXtermCell(screen, use_row, use_col, test);
 2313         } else if (screen->char_was_written
 2314                || getXtermCell(screen, use_row, use_col) >= ' ') {
 2315         addXtermCombining(screen, use_row, use_col, c);
 2316         } else {
 2317         /*
 2318          * none of the above... we will add the combining character as
 2319          * a base character.
 2320          */
 2321         used = False;
 2322         }
 2323 
 2324         if (used) {
 2325         if (!screen->scroll_amt)
 2326             ScrnUpdate(xw, use_row, use_col, 1, 1, 1);
 2327         continue;
 2328         }
 2329     }
 2330 #endif
 2331 
 2332     /* Intercept characters for printer controller mode */
 2333     if (PrinterOf(screen).printer_controlmode == 2) {
 2334         if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0)
 2335         continue;
 2336     }
 2337 
 2338     /*
 2339      * VT52 is a little ugly in the one place it has a parameterized
 2340      * control sequence, since the parameter falls after the character
 2341      * that denotes the type of sequence.
 2342      */
 2343 #if OPT_VT52_MODE
 2344     if (sp->vt52_cup) {
 2345         if (nparam < NPARAM - 1) {
 2346         SetParam(nparam++, (int) (c & 0x7f) - 32);
 2347         parms.is_sub[nparam] = 0;
 2348         }
 2349         if (nparam < 2)
 2350         continue;
 2351         sp->vt52_cup = False;
 2352         CursorSet(screen, zero_if_default(0), zero_if_default(1), xw->flags);
 2353         sp->parsestate = vt52_table;
 2354         SetParam(0, 0);
 2355         SetParam(1, 0);
 2356         continue;
 2357     }
 2358 #endif
 2359 
 2360     laststate = sp->nextstate;
 2361     if (c == ANSI_DEL
 2362         && sp->parsestate == sp->groundtable
 2363         && sp->scssize == 96
 2364         && sp->scstype != 0) {
 2365         /*
 2366          * Handle special case of shifts for 96-character sets by checking
 2367          * if we have a DEL.  The other special case for SPACE will always
 2368          * be printable.
 2369          */
 2370         sp->nextstate = CASE_PRINT;
 2371     } else
 2372 #if OPT_WIDE_CHARS
 2373     if (c > 255) {
 2374         /*
 2375          * The parsing tables all have 256 entries.  If we're supporting
 2376          * wide characters, we handle them by treating them the same as
 2377          * printing characters.
 2378          */
 2379         if (sp->parsestate == sp->groundtable) {
 2380         sp->nextstate = CASE_PRINT;
 2381         } else if (sp->parsestate == sos_table) {
 2382         c &= WIDEST_ICHAR;
 2383         if (c > 255) {
 2384             TRACE(("Found code > 255 while in SOS state: %04X\n", c));
 2385             c = BAD_ASCII;
 2386         }
 2387         } else {
 2388         sp->nextstate = CASE_GROUND_STATE;
 2389         }
 2390     } else
 2391 #endif
 2392         sp->nextstate = sp->parsestate[E2A(c)];
 2393 
 2394 #if OPT_BROKEN_OSC
 2395     /*
 2396      * Linux console palette escape sequences start with an OSC, but do
 2397      * not terminate correctly.  Some scripts do not check before writing
 2398      * them, making xterm appear to hang (it's awaiting a valid string
 2399      * terminator).  Just ignore these if we see them - there's no point
 2400      * in emulating bad code.
 2401      */
 2402     if (screen->brokenLinuxOSC
 2403         && sp->parsestate == sos_table) {
 2404         if (sp->string_used) {
 2405         switch (sp->string_area[0]) {
 2406         case 'P':
 2407             if (sp->string_used <= 7)
 2408             break;
 2409             /* FALLTHRU */
 2410         case 'R':
 2411             illegal_parse(xw, c, sp);
 2412             TRACE(("Reset to ground state (brokenLinuxOSC)\n"));
 2413             break;
 2414         }
 2415         }
 2416     }
 2417 #endif
 2418 
 2419 #if OPT_BROKEN_ST
 2420     /*
 2421      * Before patch #171, carriage control embedded within an OSC string
 2422      * would terminate it.  Some (buggy, of course) applications rely on
 2423      * this behavior.  Accommodate them by allowing one to compile xterm
 2424      * and emulate the old behavior.
 2425      */
 2426     if (screen->brokenStringTerm
 2427         && sp->parsestate == sos_table
 2428         && c < 32) {
 2429         switch (c) {
 2430         case ANSI_EOT:  /* FALLTHRU */
 2431         case ANSI_BS:   /* FALLTHRU */
 2432         case ANSI_HT:   /* FALLTHRU */
 2433         case ANSI_LF:   /* FALLTHRU */
 2434         case ANSI_VT:   /* FALLTHRU */
 2435         case ANSI_FF:   /* FALLTHRU */
 2436         case ANSI_CR:   /* FALLTHRU */
 2437         case ANSI_SO:   /* FALLTHRU */
 2438         case ANSI_SI:   /* FALLTHRU */
 2439         case ANSI_XON:  /* FALLTHRU */
 2440         case ANSI_CAN:
 2441         illegal_parse(xw, c, sp);
 2442         TRACE(("Reset to ground state (brokenStringTerm)\n"));
 2443         break;
 2444         }
 2445     }
 2446 #endif
 2447 
 2448 #if OPT_C1_PRINT
 2449     /*
 2450      * This is not completely foolproof, but will allow an application
 2451      * with values in the C1 range to use them as printable characters,
 2452      * provided that they are not intermixed with an escape sequence.
 2453      */
 2454     if (screen->c1_printable
 2455         && (c >= 128 && c < 256)) {
 2456         sp->nextstate = (sp->parsestate == esc_table
 2457                  ? CASE_ESC_IGNORE
 2458                  : sp->parsestate[E2A(160)]);
 2459         TRACE(("allowC1Printable %04X %s ->%s\n",
 2460            c, which_table(sp->parsestate),
 2461            visibleVTparse(sp->nextstate)));
 2462     }
 2463 #endif
 2464 
 2465 #if OPT_WIDE_CHARS
 2466     /*
 2467      * If we have a C1 code and the c1_printable flag is not set, simply
 2468      * ignore it when it was translated from UTF-8.  That is because the
 2469      * value could not have been present as-is in the UTF-8.
 2470      *
 2471      * To see that CASE_IGNORE is a consistent value, note that it is
 2472      * always used for NUL and other uninteresting C0 controls.
 2473      */
 2474 #if OPT_C1_PRINT
 2475     if (!screen->c1_printable)
 2476 #endif
 2477         if (screen->wide_chars
 2478         && (c >= 128 && c < 160)) {
 2479         sp->nextstate = CASE_IGNORE;
 2480         }
 2481 
 2482     /*
 2483      * If this character is a different width than the last one, put the
 2484      * previous text into the buffer and draw it now.
 2485      */
 2486     this_is_wide = isWide((int) c);
 2487     if (this_is_wide != sp->last_was_wide) {
 2488         WriteNow();
 2489     }
 2490 #endif
 2491 
 2492     /*
 2493      * Accumulate string for printable text.  This may be 8/16-bit
 2494      * characters.
 2495      */
 2496     if (sp->nextstate == CASE_PRINT) {
 2497         SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size);
 2498         if (new_string == 0) {
 2499         xtermWarning("Cannot allocate %lu bytes for printable text\n",
 2500                  (unsigned long) new_length);
 2501         continue;
 2502         }
 2503         SafeFree(sp->print_area, sp->print_size);
 2504 #if OPT_VT52_MODE
 2505         /*
 2506          * Strip output text to 7-bits for VT52.  We should do this for
 2507          * VT100 also (which is a 7-bit device), but xterm has been
 2508          * doing this for so long we shouldn't change this behavior.
 2509          */
 2510         if (screen->vtXX_level < 1)
 2511         c &= 0x7f;
 2512 #endif
 2513         sp->print_area[sp->print_used++] = (IChar) c;
 2514         sp->lastchar = thischar = (int) c;
 2515 #if OPT_WIDE_CHARS
 2516         sp->last_was_wide = this_is_wide;
 2517 #endif
 2518         if (morePtyData(screen, VTbuffer)) {
 2519         continue;
 2520         }
 2521     }
 2522 
 2523     if (sp->nextstate == CASE_PRINT
 2524         || (laststate == CASE_PRINT && sp->print_used)) {
 2525         WriteNow();
 2526     }
 2527 
 2528     /*
 2529      * Accumulate string for APC, DCS, PM, OSC, SOS controls
 2530      * This should always be 8-bit characters.
 2531      */
 2532     if (sp->parsestate == sos_table) {
 2533         SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size);
 2534         if (new_string == 0) {
 2535         xtermWarning("Cannot allocate %lu bytes for string mode %d\n",
 2536                  (unsigned long) new_length, sp->string_mode);
 2537         continue;
 2538         }
 2539         SafeFree(sp->string_area, sp->string_size);
 2540 #if OPT_WIDE_CHARS
 2541         /*
 2542          * We cannot display codes above 255, but let's try to
 2543          * accommodate the application a little by not aborting the
 2544          * string.
 2545          */
 2546         if ((c & WIDEST_ICHAR) > 255) {
 2547         sp->nextstate = CASE_PRINT;
 2548         c = BAD_ASCII;
 2549         }
 2550 #endif
 2551         sp->string_area[(sp->string_used)++] = CharOf(c);
 2552     } else if (sp->parsestate != esc_table) {
 2553         /* if we were accumulating, we're not any more */
 2554         sp->string_mode = 0;
 2555         sp->string_used = 0;
 2556     }
 2557 
 2558     DumpParams();
 2559     TRACE(("parse %04X -> %s %s (used=%lu)\n",
 2560            c, visibleVTparse(sp->nextstate),
 2561            which_table(sp->parsestate),
 2562            (unsigned long) sp->string_used));
 2563 
 2564     /*
 2565      * If the parameter list has subparameters (tokens separated by ":")
 2566      * reject any controls that do not accept subparameters.
 2567      */
 2568     if (parms.has_subparams) {
 2569         switch (sp->nextstate) {
 2570         case CASE_GROUND_STATE:
 2571         case CASE_CSI_IGNORE:
 2572         /* FALLTHRU */
 2573 
 2574         case CASE_ESC_DIGIT:
 2575         case CASE_ESC_SEMI:
 2576         case CASE_ESC_COLON:
 2577         /* these states are required to parse parameter lists */
 2578         break;
 2579 
 2580         case CASE_SGR:
 2581         TRACE(("...possible subparam usage\n"));
 2582         break;
 2583 
 2584         case CASE_CSI_DEC_DOLLAR_STATE:
 2585         case CASE_CSI_DOLLAR_STATE:
 2586         case CASE_CSI_HASH_STATE:
 2587         case CASE_CSI_EX_STATE:
 2588         case CASE_CSI_QUOTE_STATE:
 2589         case CASE_CSI_SPACE_STATE:
 2590         case CASE_CSI_STAR_STATE:
 2591         case CASE_CSI_TICK_STATE:
 2592         case CASE_DEC2_STATE:
 2593         case CASE_DEC3_STATE:
 2594         case CASE_DEC_STATE:
 2595         /* use this branch when we do not yet have the final character */
 2596         TRACE(("...unexpected subparam usage\n"));
 2597         InitParams();
 2598         sp->nextstate = CASE_CSI_IGNORE;
 2599         break;
 2600 
 2601         default:
 2602         /* use this branch for cases where we have the final character
 2603          * in the table that processed the parameter list.
 2604          */
 2605         TRACE(("...unexpected subparam usage\n"));
 2606         ResetState(sp);
 2607         continue;
 2608         }
 2609     }
 2610 
 2611     if (xw->work.palette_changed) {
 2612         repaintWhenPaletteChanged(xw, sp);
 2613     }
 2614 
 2615     switch (sp->nextstate) {
 2616     case CASE_PRINT:
 2617         TRACE(("CASE_PRINT - printable characters\n"));
 2618         break;
 2619 
 2620     case CASE_GROUND_STATE:
 2621         TRACE(("CASE_GROUND_STATE - exit ignore mode\n"));
 2622         ResetState(sp);
 2623         break;
 2624 
 2625     case CASE_IGNORE:
 2626         TRACE(("CASE_IGNORE - Ignore character %02X\n", c));
 2627         break;
 2628 
 2629     case CASE_ENQ:
 2630         TRACE(("CASE_ENQ - answerback\n"));
 2631         for (count = 0; screen->answer_back[count] != 0; count++)
 2632         unparseputc(xw, screen->answer_back[count]);
 2633         unparse_end(xw);
 2634         break;
 2635 
 2636     case CASE_BELL:
 2637         TRACE(("CASE_BELL - bell\n"));
 2638         if (sp->string_mode == ANSI_OSC) {
 2639         if (sp->string_used)
 2640             sp->string_area[--(sp->string_used)] = '\0';
 2641         do_osc(xw, sp->string_area, sp->string_used, (int) c);
 2642         ResetState(sp);
 2643         } else {
 2644         /* bell */
 2645         Bell(xw, XkbBI_TerminalBell, 0);
 2646         }
 2647         break;
 2648 
 2649     case CASE_BS:
 2650         TRACE(("CASE_BS - backspace\n"));
 2651         CursorBack(xw, 1);
 2652         break;
 2653 
 2654     case CASE_CR:
 2655         TRACE(("CASE_CR\n"));
 2656         CarriageReturn(xw);
 2657         break;
 2658 
 2659     case CASE_ESC:
 2660         if_OPT_VT52_MODE(screen, {
 2661         sp->parsestate = vt52_esc_table;
 2662         break;
 2663         });
 2664         sp->parsestate = esc_table;
 2665         break;
 2666 
 2667 #if OPT_VT52_MODE
 2668     case CASE_VT52_CUP:
 2669         TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n"));
 2670         sp->vt52_cup = True;
 2671         ResetState(sp);
 2672         break;
 2673 
 2674     case CASE_VT52_IGNORE:
 2675         TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n"));
 2676         sp->parsestate = vt52_ignore_table;
 2677         break;
 2678 #endif
 2679 
 2680     case CASE_VMOT:
 2681         TRACE(("CASE_VMOT\n"));
 2682         /*
 2683          * form feed, line feed, vertical tab
 2684          */
 2685         xtermAutoPrint(xw, c);
 2686         xtermIndex(xw, 1);
 2687         if (xw->flags & LINEFEED)
 2688         CarriageReturn(xw);
 2689         else
 2690         do_xevents(xw);
 2691         break;
 2692 
 2693     case CASE_CBT:
 2694         TRACE(("CASE_CBT\n"));
 2695         /* cursor backward tabulation */
 2696         count = one_if_default(0);
 2697         while ((count-- > 0)
 2698            && (TabToPrevStop(xw))) ;
 2699         ResetState(sp);
 2700         break;
 2701 
 2702     case CASE_CHT:
 2703         TRACE(("CASE_CHT\n"));
 2704         /* cursor forward tabulation */
 2705         count = one_if_default(0);
 2706         while ((count-- > 0)
 2707            && (TabToNextStop(xw))) ;
 2708         ResetState(sp);
 2709         break;
 2710 
 2711     case CASE_TAB:
 2712         /* tab */
 2713         TabToNextStop(xw);
 2714         break;
 2715 
 2716     case CASE_SI:
 2717         screen->curgl = 0;
 2718         if_OPT_VT52_MODE(screen, {
 2719         ResetState(sp);
 2720         });
 2721         break;
 2722 
 2723     case CASE_SO:
 2724         screen->curgl = 1;
 2725         if_OPT_VT52_MODE(screen, {
 2726         ResetState(sp);
 2727         });
 2728         break;
 2729 
 2730     case CASE_DECDHL:
 2731         xterm_DECDHL(xw, c == '3');
 2732         ResetState(sp);
 2733         break;
 2734 
 2735     case CASE_DECSWL:
 2736         xterm_DECSWL(xw);
 2737         ResetState(sp);
 2738         break;
 2739 
 2740     case CASE_DECDWL:
 2741         xterm_DECDWL(xw);
 2742         ResetState(sp);
 2743         break;
 2744 
 2745     case CASE_SCR_STATE:
 2746         /* enter scr state */
 2747         sp->parsestate = scrtable;
 2748         break;
 2749 
 2750     case CASE_SCS0_STATE:
 2751         /* enter scs state 0 */
 2752         select_charset(sp, 0, 94);
 2753         break;
 2754 
 2755     case CASE_SCS1_STATE:
 2756         /* enter scs state 1 */
 2757         select_charset(sp, 1, 94);
 2758         break;
 2759 
 2760     case CASE_SCS2_STATE:
 2761         /* enter scs state 2 */
 2762         select_charset(sp, 2, 94);
 2763         break;
 2764 
 2765     case CASE_SCS3_STATE:
 2766         /* enter scs state 3 */
 2767         select_charset(sp, 3, 94);
 2768         break;
 2769 
 2770     case CASE_SCS1A_STATE:
 2771         /* enter scs state 1 */
 2772         select_charset(sp, 1, 96);
 2773         break;
 2774 
 2775     case CASE_SCS2A_STATE:
 2776         /* enter scs state 2 */
 2777         select_charset(sp, 2, 96);
 2778         break;
 2779 
 2780     case CASE_SCS3A_STATE:
 2781         /* enter scs state 3 */
 2782         select_charset(sp, 3, 96);
 2783         break;
 2784 
 2785     case CASE_ESC_IGNORE:
 2786         /* unknown escape sequence */
 2787         sp->parsestate = eigtable;
 2788         break;
 2789 
 2790     case CASE_ESC_DIGIT:
 2791         /* digit in csi or dec mode */
 2792         if (nparam > 0) {
 2793         value = zero_if_default(nparam - 1);
 2794         SetParam(nparam - 1, (10 * value) + ((int) c - '0'));
 2795         if (GetParam(nparam - 1) > 65535)
 2796             SetParam(nparam - 1, 65535);
 2797         if (sp->parsestate == csi_table)
 2798             sp->parsestate = csi2_table;
 2799         }
 2800         break;
 2801 
 2802     case CASE_ESC_SEMI:
 2803         /* semicolon in csi or dec mode */
 2804         if (nparam < NPARAM) {
 2805         parms.is_sub[nparam] = 0;
 2806         SetParam(nparam++, DEFAULT);
 2807         }
 2808         if (sp->parsestate == csi_table)
 2809         sp->parsestate = csi2_table;
 2810         break;
 2811 
 2812         /*
 2813          * A _few_ commands accept colon-separated subparameters.
 2814          * Mark the parameter list so that we can exclude (most) bogus
 2815          * commands with simple/fast checks.
 2816          */
 2817     case CASE_ESC_COLON:
 2818         if (nparam < NPARAM) {
 2819         parms.has_subparams = 1;
 2820         if (nparam == 0) {
 2821             parms.is_sub[nparam] = 1;
 2822             SetParam(nparam++, DEFAULT);
 2823         } else if (parms.is_sub[nparam - 1] == 0) {
 2824             parms.is_sub[nparam - 1] = 1;
 2825             parms.is_sub[nparam] = 2;
 2826             parms.params[nparam] = 0;
 2827             ++nparam;
 2828         } else {
 2829             parms.is_sub[nparam] = 1 + parms.is_sub[nparam - 1];
 2830             parms.params[nparam] = 0;
 2831             ++nparam;
 2832         }
 2833         }
 2834         break;
 2835 
 2836     case CASE_DEC_STATE:
 2837         /* enter dec mode */
 2838         sp->parsestate = dec_table;
 2839         break;
 2840 
 2841     case CASE_DEC2_STATE:
 2842         /* enter dec2 mode */
 2843         sp->parsestate = dec2_table;
 2844         break;
 2845 
 2846     case CASE_DEC3_STATE:
 2847         /* enter dec3 mode */
 2848         sp->parsestate = dec3_table;
 2849         break;
 2850 
 2851     case CASE_ICH:
 2852         TRACE(("CASE_ICH - insert char\n"));
 2853         InsertChar(xw, (unsigned) one_if_default(0));
 2854         ResetState(sp);
 2855         break;
 2856 
 2857     case CASE_CUU:
 2858         TRACE(("CASE_CUU - cursor up\n"));
 2859         CursorUp(screen, one_if_default(0));
 2860         ResetState(sp);
 2861         break;
 2862 
 2863     case CASE_CUD:
 2864         TRACE(("CASE_CUD - cursor down\n"));
 2865         CursorDown(screen, one_if_default(0));
 2866         ResetState(sp);
 2867         break;
 2868 
 2869     case CASE_CUF:
 2870         TRACE(("CASE_CUF - cursor forward\n"));
 2871         CursorForward(xw, one_if_default(0));
 2872         ResetState(sp);
 2873         break;
 2874 
 2875     case CASE_CUB:
 2876         TRACE(("CASE_CUB - cursor backward\n"));
 2877         CursorBack(xw, one_if_default(0));
 2878         ResetState(sp);
 2879         break;
 2880 
 2881     case CASE_CUP:
 2882         TRACE(("CASE_CUP - cursor position\n"));
 2883         if_OPT_XMC_GLITCH(screen, {
 2884         Jump_XMC(xw);
 2885         });
 2886         CursorSet(screen, one_if_default(0) - 1, one_if_default(1) - 1, xw->flags);
 2887         ResetState(sp);
 2888         break;
 2889 
 2890     case CASE_VPA:
 2891         TRACE(("CASE_VPA - vertical position absolute\n"));
 2892         CursorSet(screen, one_if_default(0) - 1, CursorCol(xw), xw->flags);
 2893         ResetState(sp);
 2894         break;
 2895 
 2896     case CASE_HPA:
 2897         TRACE(("CASE_HPA - horizontal position absolute\n"));
 2898         CursorSet(screen, CursorRow(xw), one_if_default(0) - 1, xw->flags);
 2899         ResetState(sp);
 2900         break;
 2901 
 2902     case CASE_VPR:
 2903         TRACE(("CASE_VPR - vertical position relative\n"));
 2904         CursorSet(screen,
 2905               CursorRow(xw) + one_if_default(0),
 2906               CursorCol(xw),
 2907               xw->flags);
 2908         ResetState(sp);
 2909         break;
 2910 
 2911     case CASE_HPR:
 2912         TRACE(("CASE_HPR - horizontal position relative\n"));
 2913         CursorSet(screen,
 2914               CursorRow(xw),
 2915               CursorCol(xw) + one_if_default(0),
 2916               xw->flags);
 2917         ResetState(sp);
 2918         break;
 2919 
 2920     case CASE_HP_BUGGY_LL:
 2921         TRACE(("CASE_HP_BUGGY_LL\n"));
 2922         /* Some HP-UX applications have the bug that they
 2923            assume ESC F goes to the lower left corner of
 2924            the screen, regardless of what terminfo says. */
 2925         if (screen->hp_ll_bc)
 2926         CursorSet(screen, screen->max_row, 0, xw->flags);
 2927         ResetState(sp);
 2928         break;
 2929 
 2930     case CASE_ED:
 2931         TRACE(("CASE_ED - erase display\n"));
 2932         do_cd_xtra_scroll(xw);
 2933         do_erase_display(xw, zero_if_default(0), OFF_PROTECT);
 2934         ResetState(sp);
 2935         break;
 2936 
 2937     case CASE_EL:
 2938         TRACE(("CASE_EL - erase line\n"));
 2939         do_erase_line(xw, zero_if_default(0), OFF_PROTECT);
 2940         ResetState(sp);
 2941         break;
 2942 
 2943     case CASE_ECH:
 2944         TRACE(("CASE_ECH - erase char\n"));
 2945         /* ECH */
 2946         ClearRight(xw, one_if_default(0));
 2947         ResetState(sp);
 2948         break;
 2949 
 2950     case CASE_IL:
 2951         TRACE(("CASE_IL - insert line\n"));
 2952         InsertLine(xw, one_if_default(0));
 2953         ResetState(sp);
 2954         break;
 2955 
 2956     case CASE_DL:
 2957         TRACE(("CASE_DL - delete line\n"));
 2958         DeleteLine(xw, one_if_default(0));
 2959         ResetState(sp);
 2960         break;
 2961 
 2962     case CASE_DCH:
 2963         TRACE(("CASE_DCH - delete char\n"));
 2964         DeleteChar(xw, (unsigned) one_if_default(0));
 2965         ResetState(sp);
 2966         break;
 2967 
 2968     case CASE_TRACK_MOUSE:
 2969         /*
 2970          * A single parameter other than zero is always scroll-down.
 2971          * A zero-parameter is used to reset the mouse mode, and is
 2972          * not useful for scrolling anyway.
 2973          */
 2974         if (nparam > 1 || GetParam(0) == 0) {
 2975         CELL start;
 2976 
 2977         TRACE(("CASE_TRACK_MOUSE\n"));
 2978         /* Track mouse as long as in window and between
 2979          * specified rows
 2980          */
 2981         start.row = one_if_default(2) - 1;
 2982         start.col = GetParam(1) - 1;
 2983         TrackMouse(xw,
 2984                GetParam(0),
 2985                &start,
 2986                GetParam(3) - 1, GetParam(4) - 2);
 2987         } else {
 2988         TRACE(("CASE_SD - scroll down\n"));
 2989         /* SD */
 2990         RevScroll(xw, one_if_default(0));
 2991         do_xevents(xw);
 2992         }
 2993         ResetState(sp);
 2994         break;
 2995 
 2996     case CASE_SD:
 2997         /*
 2998          * Cater to ECMA-48's typographical error...
 2999          */
 3000         TRACE(("CASE_SD - scroll down\n"));
 3001         RevScroll(xw, one_if_default(0));
 3002         do_xevents(xw);
 3003         ResetState(sp);
 3004         break;
 3005 
 3006     case CASE_DECID:
 3007         TRACE(("CASE_DECID\n"));
 3008         if_OPT_VT52_MODE(screen, {
 3009         unparseputc(xw, ANSI_ESC);
 3010         unparseputc(xw, '/');
 3011         unparseputc(xw, 'Z');
 3012         unparse_end(xw);
 3013         ResetState(sp);
 3014         break;
 3015         });
 3016         SetParam(0, DEFAULT);   /* Default ID parameter */
 3017         /* FALLTHRU */
 3018     case CASE_DA1:
 3019         TRACE(("CASE_DA1\n"));
 3020         if (GetParam(0) <= 0) { /* less than means DEFAULT */
 3021         count = 0;
 3022         init_reply(ANSI_CSI);
 3023         reply.a_pintro = '?';
 3024 
 3025         /*
 3026          * The first parameter corresponds to the highest operating
 3027          * level (i.e., service level) of the emulation.  A DEC
 3028          * terminal can be setup to respond with a different DA
 3029          * response, but there's no control sequence that modifies
 3030          * this.  We set it via a resource.
 3031          */
 3032         if (screen->terminal_id < 200) {
 3033             switch (screen->terminal_id) {
 3034             case 125:
 3035             reply.a_param[count++] = 12;    /* VT125 */
 3036 #if OPT_REGIS_GRAPHICS
 3037             reply.a_param[count++] = 0 | 2 | 1; /* no STP, AVO, GPO (ReGIS) */
 3038 #else
 3039             reply.a_param[count++] = 0 | 2 | 0; /* no STP, AVO, no GPO (ReGIS) */
 3040 #endif
 3041             reply.a_param[count++] = 0; /* no printer */
 3042             reply.a_param[count++] = XTERM_PATCH;   /* ROM version */
 3043             break;
 3044             case 102:
 3045             reply.a_param[count++] = 6; /* VT102 */
 3046             break;
 3047             case 101:
 3048             reply.a_param[count++] = 1; /* VT101 */
 3049             reply.a_param[count++] = 0; /* no options */
 3050             break;
 3051             default:    /* VT100 */
 3052             reply.a_param[count++] = 1; /* VT100 */
 3053             reply.a_param[count++] = 0 | 2 | 0; /* no STP, AVO, no GPO (ReGIS) */
 3054             break;
 3055             }
 3056         } else {
 3057             reply.a_param[count++] = (ParmType) (60
 3058                              + screen->terminal_id
 3059                              / 100);
 3060             reply.a_param[count++] = 1;     /* 132-columns */
 3061             reply.a_param[count++] = 2;     /* printer */
 3062 #if OPT_REGIS_GRAPHICS
 3063             if (optRegisGraphics(screen)) {
 3064             reply.a_param[count++] = 3; /* ReGIS graphics */
 3065             }
 3066 #endif
 3067 #if OPT_SIXEL_GRAPHICS
 3068             if (optSixelGraphics(screen)) {
 3069             reply.a_param[count++] = 4; /* sixel graphics */
 3070             }
 3071 #endif
 3072             reply.a_param[count++] = 6;     /* selective-erase */
 3073 #if OPT_SUNPC_KBD
 3074             if (xw->keyboard.type == keyboardIsVT220)
 3075 #endif
 3076             reply.a_param[count++] = 8; /* user-defined-keys */
 3077             reply.a_param[count++] = 9;     /* national replacement charsets */
 3078             reply.a_param[count++] = 15;    /* technical characters */
 3079             reply.a_param[count++] = 16;    /* locator port */
 3080             if (screen->terminal_id >= 400) {
 3081             reply.a_param[count++] = 17;    /* terminal state interrogation */
 3082             reply.a_param[count++] = 18;    /* windowing extension */
 3083             reply.a_param[count++] = 21;    /* horizontal scrolling */
 3084             }
 3085             if_OPT_ISO_COLORS(screen, {
 3086             reply.a_param[count++] = 22;    /* ANSI color, VT525 */
 3087             });
 3088             reply.a_param[count++] = 28;    /* rectangular editing */
 3089 #if OPT_DEC_LOCATOR
 3090             reply.a_param[count++] = 29;    /* ANSI text locator */
 3091 #endif
 3092         }
 3093         reply.a_nparam = (ParmType) count;
 3094         reply.a_inters = 0;
 3095         reply.a_final = 'c';
 3096         unparseseq(xw, &reply);
 3097         }
 3098         ResetState(sp);
 3099         break;
 3100 
 3101     case CASE_DA2:
 3102         TRACE(("CASE_DA2\n"));
 3103         if (GetParam(0) <= 0) { /* less than means DEFAULT */
 3104         count = 0;
 3105         init_reply(ANSI_CSI);
 3106         reply.a_pintro = '>';
 3107 
 3108         if (screen->terminal_id >= 200) {
 3109             switch (screen->terminal_id) {
 3110             case 220:
 3111             default:
 3112             reply.a_param[count++] = 1; /* VT220 */
 3113             break;
 3114             case 240:
 3115             case 241:
 3116             /* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */
 3117             reply.a_param[count++] = 2; /* VT240 */
 3118             break;
 3119             case 320:
 3120             /* http://www.vt100.net/docs/vt320-uu/appendixe.html */
 3121             reply.a_param[count++] = 24;    /* VT320 */
 3122             break;
 3123             case 330:
 3124             reply.a_param[count++] = 18;    /* VT330 */
 3125             break;
 3126             case 340:
 3127             reply.a_param[count++] = 19;    /* VT340 */
 3128             break;
 3129             case 382:
 3130             reply.a_param[count++] = 32;    /* VT382 */
 3131             break;
 3132             case 420:
 3133             reply.a_param[count++] = 41;    /* VT420 */
 3134             break;
 3135             case 510:
 3136             /* http://www.vt100.net/docs/vt510-rm/DA2 */
 3137             reply.a_param[count++] = 61;    /* VT510 */
 3138             break;
 3139             case 520:
 3140             reply.a_param[count++] = 64;    /* VT520 */
 3141             break;
 3142             case 525:
 3143             reply.a_param[count++] = 65;    /* VT525 */
 3144             break;
 3145             }
 3146         } else {
 3147             reply.a_param[count++] = 0;     /* VT100 (nonstandard) */
 3148         }
 3149         reply.a_param[count++] = XTERM_PATCH;   /* Version */
 3150         reply.a_param[count++] = 0; /* options (none) */
 3151         reply.a_nparam = (ParmType) count;
 3152         reply.a_inters = 0;
 3153         reply.a_final = 'c';
 3154         unparseseq(xw, &reply);
 3155         }
 3156         ResetState(sp);
 3157         break;
 3158 
 3159     case CASE_DECRPTUI:
 3160         TRACE(("CASE_DECRPTUI\n"));
 3161         if ((screen->vtXX_level >= 4)
 3162         && (GetParam(0) <= 0)) {    /* less than means DEFAULT */
 3163         unparseputc1(xw, ANSI_DCS);
 3164         unparseputc(xw, '!');
 3165         unparseputc(xw, '|');
 3166         /* report the "terminal unit id" as 4 pairs of hexadecimal
 3167          * digits -- meaningless for a terminal emulator, but some
 3168          * host may care about the format.
 3169          */
 3170         for (count = 0; count < 8; ++count) {
 3171             unparseputc(xw, '0');
 3172         }
 3173         unparseputc1(xw, ANSI_ST);
 3174         unparse_end(xw);
 3175         }
 3176         ResetState(sp);
 3177         break;
 3178 
 3179     case CASE_TBC:
 3180         TRACE(("CASE_TBC - tab clear\n"));
 3181         if ((value = GetParam(0)) <= 0) /* less than means default */
 3182         TabClear(xw->tabs, screen->cur_col);
 3183         else if (value == 3)
 3184         TabZonk(xw->tabs);
 3185         ResetState(sp);
 3186         break;
 3187 
 3188     case CASE_SET:
 3189         TRACE(("CASE_SET - set mode\n"));
 3190         ansi_modes(xw, bitset);
 3191         ResetState(sp);
 3192         break;
 3193 
 3194     case CASE_RST:
 3195         TRACE(("CASE_RST - reset mode\n"));
 3196         ansi_modes(xw, bitclr);
 3197         ResetState(sp);
 3198         break;
 3199 
 3200     case CASE_SGR:
 3201         for (item = 0; item < nparam; ++item) {
 3202         int op = GetParam(item);
 3203         int skip;
 3204 
 3205         if_OPT_XMC_GLITCH(screen, {
 3206             Mark_XMC(xw, op);
 3207         });
 3208         TRACE(("CASE_SGR %d\n", op));
 3209 
 3210         /*
 3211          * Only SGR 38/48 accept subparameters, and in those cases
 3212          * the values will not be seen at this point.
 3213          */
 3214         if ((skip = param_has_subparams(item))) {
 3215             switch (op) {
 3216             case 38:
 3217             /* FALLTHRU */
 3218             case 48:
 3219             if_OPT_ISO_COLORS(screen, {
 3220                 break;
 3221             });
 3222             /* FALLTHRU */
 3223             default:
 3224             TRACE(("...unexpected subparameter in SGR\n"));
 3225             item += skip;   /* ignore this */
 3226             op = 9999;  /* will never use this, anyway */
 3227             break;
 3228             }
 3229         }
 3230 
 3231         switch (op) {
 3232         case DEFAULT:
 3233             /* FALLTHRU */
 3234         case 0:
 3235             resetRendition(xw);
 3236             if_OPT_ISO_COLORS(screen, {
 3237             reset_SGR_Colors(xw);
 3238             });
 3239             break;
 3240         case 1: /* Bold                 */
 3241             UIntSet(xw->flags, BOLD);
 3242             if_OPT_ISO_COLORS(screen, {
 3243             setExtendedFG(xw);
 3244             });
 3245             break;
 3246 #if OPT_WIDE_ATTRS
 3247         case 2: /* faint, decreased intensity or second colour */
 3248             UIntSet(xw->flags, ATR_FAINT);
 3249             if_OPT_ISO_COLORS(screen, {
 3250             setExtendedFG(xw);
 3251             });
 3252             break;
 3253         case 3: /* italicized */
 3254             setItalicFont(xw, UseItalicFont(screen));
 3255             UIntSet(xw->flags, ATR_ITALIC);
 3256             if_OPT_ISO_COLORS(screen, {
 3257             setExtendedFG(xw);
 3258             });
 3259             break;
 3260 #endif
 3261         case 4: /* Underscore           */
 3262             UIntSet(xw->flags, UNDERLINE);
 3263             if_OPT_ISO_COLORS(screen, {
 3264             setExtendedFG(xw);
 3265             });
 3266             break;
 3267         case 5: /* Blink (less than 150 per minute) */
 3268             /* FALLTHRU */
 3269         case 6: /* Blink (150 per minute, or more) */
 3270             UIntSet(xw->flags, BLINK);
 3271             StartBlinking(xw);
 3272             if_OPT_ISO_COLORS(screen, {
 3273             setExtendedFG(xw);
 3274             });
 3275             break;
 3276         case 7:
 3277             UIntSet(xw->flags, INVERSE);
 3278             if_OPT_ISO_COLORS(screen, {
 3279             setExtendedBG(xw);
 3280             });
 3281             break;
 3282         case 8:
 3283             UIntSet(xw->flags, INVISIBLE);
 3284             break;
 3285 #if OPT_WIDE_ATTRS
 3286         case 9: /* crossed-out characters */
 3287             UIntSet(xw->flags, ATR_STRIKEOUT);
 3288             break;
 3289 #endif
 3290 #if OPT_WIDE_ATTRS
 3291         case 21:    /* doubly-underlined */
 3292             UIntSet(xw->flags, ATR_DBL_UNDER);
 3293             break;
 3294 #endif
 3295         case 22:    /* reset 'bold' */
 3296             UIntClr(xw->flags, BOLD);
 3297 #if OPT_WIDE_ATTRS
 3298             UIntClr(xw->flags, ATR_FAINT);
 3299 #endif
 3300             if_OPT_ISO_COLORS(screen, {
 3301             setExtendedFG(xw);
 3302             });
 3303             break;
 3304 #if OPT_WIDE_ATTRS
 3305         case 23:    /* not italicized */
 3306             ResetItalics(xw);
 3307             if_OPT_ISO_COLORS(screen, {
 3308             setExtendedFG(xw);
 3309             });
 3310             break;
 3311 #endif
 3312         case 24:
 3313             UIntClr(xw->flags, UNDERLINE);
 3314 #if OPT_WIDE_ATTRS
 3315             UIntClr(xw->flags, ATR_DBL_UNDER);
 3316 #endif
 3317             if_OPT_ISO_COLORS(screen, {
 3318             setExtendedFG(xw);
 3319             });
 3320             break;
 3321         case 25:    /* reset 'blink' */
 3322             UIntClr(xw->flags, BLINK);
 3323             if_OPT_ISO_COLORS(screen, {
 3324             setExtendedFG(xw);
 3325             });
 3326             break;
 3327         case 27:
 3328             UIntClr(xw->flags, INVERSE);
 3329             if_OPT_ISO_COLORS(screen, {
 3330             setExtendedBG(xw);
 3331             });
 3332             break;
 3333         case 28:
 3334             UIntClr(xw->flags, INVISIBLE);
 3335             break;
 3336 #if OPT_WIDE_ATTRS
 3337         case 29:    /* not crossed out */
 3338             UIntClr(xw->flags, ATR_STRIKEOUT);
 3339             break;
 3340 #endif
 3341         case 30:
 3342             /* FALLTHRU */
 3343         case 31:
 3344             /* FALLTHRU */
 3345         case 32:
 3346             /* FALLTHRU */
 3347         case 33:
 3348             /* FALLTHRU */
 3349         case 34:
 3350             /* FALLTHRU */
 3351         case 35:
 3352             /* FALLTHRU */
 3353         case 36:
 3354             /* FALLTHRU */
 3355         case 37:
 3356             if_OPT_ISO_COLORS(screen, {
 3357             xw->sgr_foreground = (op - 30);
 3358             xw->sgr_38_xcolors = False;
 3359             clrDirectFG(xw->flags);
 3360             setExtendedFG(xw);
 3361             });
 3362             break;
 3363         case 38:
 3364             /* This is more complicated than I'd like, but it should
 3365              * properly eat all the parameters for unsupported modes.
 3366              */
 3367             if_OPT_ISO_COLORS(screen, {
 3368             Boolean extended;
 3369             if (parse_extended_colors(xw, &value, &item,
 3370                           &extended)) {
 3371                 xw->sgr_foreground = value;
 3372                 xw->sgr_38_xcolors = True;
 3373                 setDirectFG(xw->flags, extended);
 3374                 setExtendedFG(xw);
 3375             }
 3376             });
 3377             break;
 3378         case 39:
 3379             if_OPT_ISO_COLORS(screen, {
 3380             reset_SGR_Foreground(xw);
 3381             });
 3382             break;
 3383         case 40:
 3384             /* FALLTHRU */
 3385         case 41:
 3386             /* FALLTHRU */
 3387         case 42:
 3388             /* FALLTHRU */
 3389         case 43:
 3390             /* FALLTHRU */
 3391         case 44:
 3392             /* FALLTHRU */
 3393         case 45:
 3394             /* FALLTHRU */
 3395         case 46:
 3396             /* FALLTHRU */
 3397         case 47:
 3398             if_OPT_ISO_COLORS(screen, {
 3399             xw->sgr_background = (op - 40);
 3400             clrDirectBG(xw->flags);
 3401             setExtendedBG(xw);
 3402             });
 3403             break;
 3404         case 48:
 3405             if_OPT_ISO_COLORS(screen, {
 3406             Boolean extended;
 3407             if (parse_extended_colors(xw, &value, &item,
 3408                           &extended)) {
 3409                 xw->sgr_background = value;
 3410                 setDirectBG(xw->flags, extended);
 3411                 setExtendedBG(xw);
 3412             }
 3413             });
 3414             break;
 3415         case 49:
 3416             if_OPT_ISO_COLORS(screen, {
 3417             reset_SGR_Background(xw);
 3418             });
 3419             break;
 3420         case 90:
 3421             /* FALLTHRU */
 3422         case 91:
 3423             /* FALLTHRU */
 3424         case 92:
 3425             /* FALLTHRU */
 3426         case 93:
 3427             /* FALLTHRU */
 3428         case 94:
 3429             /* FALLTHRU */
 3430         case 95:
 3431             /* FALLTHRU */
 3432         case 96:
 3433             /* FALLTHRU */
 3434         case 97:
 3435             if_OPT_AIX_COLORS(screen, {
 3436             xw->sgr_foreground = (op - 90 + 8);
 3437             clrDirectFG(xw->flags);
 3438             setExtendedFG(xw);
 3439             });
 3440             break;
 3441         case 100:
 3442 #if !OPT_AIX_COLORS
 3443             if_OPT_ISO_COLORS(screen, {
 3444             reset_SGR_Foreground(xw);
 3445             reset_SGR_Background(xw);
 3446             });
 3447             break;
 3448 #endif
 3449         case 101:
 3450             /* FALLTHRU */
 3451         case 102:
 3452             /* FALLTHRU */
 3453         case 103:
 3454             /* FALLTHRU */
 3455         case 104:
 3456             /* FALLTHRU */
 3457         case 105:
 3458             /* FALLTHRU */
 3459         case 106:
 3460             /* FALLTHRU */
 3461         case 107:
 3462             if_OPT_AIX_COLORS(screen, {
 3463             xw->sgr_background = (op - 100 + 8);
 3464             clrDirectBG(xw->flags);
 3465             setExtendedBG(xw);
 3466             });
 3467             break;
 3468         }
 3469         }
 3470         ResetState(sp);
 3471         break;
 3472 
 3473         /* DSR (except for the '?') is a superset of CPR */
 3474     case CASE_DSR:
 3475         sp->private_function = True;
 3476 
 3477         /* FALLTHRU */
 3478     case CASE_CPR:
 3479         TRACE(("CASE_DSR - device status report\n"));
 3480         count = 0;
 3481         init_reply(ANSI_CSI);
 3482         reply.a_pintro = CharOf(sp->private_function ? '?' : 0);
 3483         reply.a_inters = 0;
 3484         reply.a_final = 'n';
 3485 
 3486         switch (GetParam(0)) {
 3487         case 5:
 3488         TRACE(("...request operating status\n"));
 3489         /* operating status */
 3490         reply.a_param[count++] = 0; /* (no malfunction ;-) */
 3491         break;
 3492         case 6:
 3493         TRACE(("...request %s\n",
 3494                (sp->private_function
 3495             ? "DECXCPR"
 3496             : "CPR")));
 3497         /* CPR */
 3498         /* DECXCPR (with page=1) */
 3499         value = (screen->cur_row + 1);
 3500         if ((xw->flags & ORIGIN) != 0) {
 3501             value -= screen->top_marg;
 3502         }
 3503         reply.a_param[count++] = (ParmType) value;
 3504 
 3505         value = (screen->cur_col + 1);
 3506         if ((xw->flags & ORIGIN) != 0) {
 3507             value -= screen->lft_marg;
 3508         }
 3509         reply.a_param[count++] = (ParmType) value;
 3510 
 3511         if (sp->private_function
 3512             && screen->vtXX_level >= 4) {   /* VT420 */
 3513             reply.a_param[count++] = 1;
 3514         }
 3515         reply.a_final = 'R';
 3516         break;
 3517         case 15:
 3518         TRACE(("...request printer status\n"));
 3519         if (sp->private_function
 3520             && screen->vtXX_level >= 2) {   /* VT220 */
 3521             reply.a_param[count++] = 13;    /* no printer detected */
 3522         }
 3523         break;
 3524         case 25:
 3525         TRACE(("...request UDK status\n"));
 3526         if (sp->private_function
 3527             && screen->vtXX_level >= 2) {   /* VT220 */
 3528             reply.a_param[count++] = 20;    /* UDK always unlocked */
 3529         }
 3530         break;
 3531         case 26:
 3532         TRACE(("...request keyboard status\n"));
 3533         if (sp->private_function
 3534             && screen->vtXX_level >= 2) {   /* VT220 */
 3535             reply.a_param[count++] = 27;
 3536             reply.a_param[count++] = 1;     /* North American */
 3537             if (screen->vtXX_level >= 3) {  /* VT320 */
 3538             reply.a_param[count++] = 0; /* ready */
 3539             }
 3540             if (screen->vtXX_level >= 4) {  /* VT420 */
 3541             reply.a_param[count++] = 0; /* LK201 */
 3542             }
 3543         }
 3544         break;
 3545         case 53:        /* according to existing xterm handling */
 3546         /* FALLTHRU */
 3547         case 55:        /* according to the VT330/VT340 Text Programming Manual */
 3548         TRACE(("...request locator status\n"));
 3549         if (sp->private_function
 3550             && screen->vtXX_level >= 3) {   /* VT330 */
 3551 #if OPT_DEC_LOCATOR
 3552             reply.a_param[count++] = 50;    /* locator ready */
 3553 #else
 3554             reply.a_param[count++] = 53;    /* no locator */
 3555 #endif
 3556         }
 3557         break;
 3558         case 56:
 3559         TRACE(("...request locator type\n"));
 3560         if (sp->private_function
 3561             && screen->vtXX_level >= 3) {   /* VT330 */
 3562             reply.a_param[count++] = 57;
 3563 #if OPT_DEC_LOCATOR
 3564             reply.a_param[count++] = 1;     /* mouse */
 3565 #else
 3566             reply.a_param[count++] = 0;     /* unknown */
 3567 #endif
 3568         }
 3569         break;
 3570         case 62:
 3571         TRACE(("...request DECMSR - macro space\n"));
 3572         if (sp->private_function
 3573             && screen->vtXX_level >= 4) {   /* VT420 */
 3574             reply.a_pintro = 0;
 3575             reply.a_radix[count] = 16;  /* no data */
 3576             reply.a_param[count++] = 0;     /* no space for macros */
 3577             reply.a_inters = '*';
 3578             reply.a_final = L_CURL;
 3579         }
 3580         break;
 3581         case 63:
 3582         TRACE(("...request DECCKSR - memory checksum\n"));
 3583         /* DECCKSR - Memory checksum */
 3584         if (sp->private_function
 3585             && screen->vtXX_level >= 4) {   /* VT420 */
 3586             init_reply(ANSI_DCS);
 3587             reply.a_param[count++] = (ParmType) GetParam(1);    /* PID */
 3588             reply.a_delim = "!~";   /* delimiter */
 3589             reply.a_radix[count] = 16;  /* use hex */
 3590             reply.a_param[count++] = 0;     /* no data */
 3591         }
 3592         break;
 3593         case 75:
 3594         TRACE(("...request data integrity\n"));
 3595         if (sp->private_function
 3596             && screen->vtXX_level >= 4) {   /* VT420 */
 3597             reply.a_param[count++] = 70;    /* no errors */
 3598         }
 3599         break;
 3600         case 85:
 3601         TRACE(("...request multi-session configuration\n"));
 3602         if (sp->private_function
 3603             && screen->vtXX_level >= 4) {   /* VT420 */
 3604             reply.a_param[count++] = 83;    /* not configured */
 3605         }
 3606         break;
 3607         default:
 3608         break;
 3609         }
 3610 
 3611         if ((reply.a_nparam = (ParmType) count) != 0)
 3612         unparseseq(xw, &reply);
 3613 
 3614         ResetState(sp);
 3615         sp->private_function = False;
 3616         break;
 3617 
 3618     case CASE_MC:
 3619         TRACE(("CASE_MC - media control\n"));
 3620         xtermMediaControl(xw, GetParam(0), False);
 3621         ResetState(sp);
 3622         break;
 3623 
 3624     case CASE_DEC_MC:
 3625         TRACE(("CASE_DEC_MC - DEC media control\n"));
 3626         xtermMediaControl(xw, GetParam(0), True);
 3627         ResetState(sp);
 3628         break;
 3629 
 3630     case CASE_HP_MEM_LOCK:
 3631         /* FALLTHRU */
 3632     case CASE_HP_MEM_UNLOCK:
 3633         TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK)
 3634                 ? "CASE_HP_MEM_LOCK"
 3635                 : "CASE_HP_MEM_UNLOCK")));
 3636         if (screen->scroll_amt)
 3637         FlushScroll(xw);
 3638         if (sp->parsestate[c] == CASE_HP_MEM_LOCK)
 3639         set_tb_margins(screen, screen->cur_row, screen->bot_marg);
 3640         else
 3641         set_tb_margins(screen, 0, screen->bot_marg);
 3642         ResetState(sp);
 3643         break;
 3644 
 3645     case CASE_DECSTBM:
 3646         TRACE(("CASE_DECSTBM - set scrolling region\n"));
 3647         {
 3648         int top;
 3649         int bot;
 3650         top = one_if_default(0);
 3651         if (nparam < 2 || (bot = GetParam(1)) == DEFAULT
 3652             || bot > MaxRows(screen)
 3653             || bot == 0)
 3654             bot = MaxRows(screen);
 3655         if (bot > top) {
 3656             if (screen->scroll_amt)
 3657             FlushScroll(xw);
 3658             set_tb_margins(screen, top - 1, bot - 1);
 3659             CursorSet(screen, 0, 0, xw->flags);
 3660         }
 3661         ResetState(sp);
 3662         }
 3663         break;
 3664 
 3665     case CASE_DECREQTPARM:
 3666         TRACE(("CASE_DECREQTPARM\n"));
 3667         if (screen->terminal_id < 200) {    /* VT102 */
 3668         value = zero_if_default(0);
 3669         if (value == 0 || value == 1) {
 3670             init_reply(ANSI_CSI);
 3671             reply.a_pintro = 0;
 3672             reply.a_nparam = 7;
 3673             reply.a_param[0] = (ParmType) (value + 2);
 3674             reply.a_param[1] = 1;   /* no parity */
 3675             reply.a_param[2] = 1;   /* eight bits */
 3676             reply.a_param[3] = 128; /* transmit 38.4k baud */
 3677             reply.a_param[4] = 128; /* receive 38.4k baud */
 3678             reply.a_param[5] = 1;   /* clock multiplier ? */
 3679             reply.a_param[6] = 0;   /* STP flags ? */
 3680             reply.a_inters = 0;
 3681             reply.a_final = 'x';
 3682             unparseseq(xw, &reply);
 3683         }
 3684         }
 3685         ResetState(sp);
 3686         break;
 3687 
 3688     case CASE_DECSET:
 3689         /* DECSET */
 3690 #if OPT_VT52_MODE
 3691         if (screen->vtXX_level != 0)
 3692 #endif
 3693         dpmodes(xw, bitset);
 3694         ResetState(sp);
 3695 #if OPT_TEK4014
 3696         if (TEK4014_ACTIVE(xw)) {
 3697         TRACE(("Tek4014 is now active...\n"));
 3698         return False;
 3699         }
 3700 #endif
 3701         break;
 3702 
 3703     case CASE_DECRST:
 3704         /* DECRST */
 3705         dpmodes(xw, bitclr);
 3706         init_groundtable(screen, sp);
 3707         ResetState(sp);
 3708         break;
 3709 
 3710     case CASE_DECALN:
 3711         TRACE(("CASE_DECALN - alignment test\n"));
 3712         if (screen->cursor_state)
 3713         HideCursor();
 3714         /*
 3715          * DEC STD 070 does not mention left/right margins.  Likely the
 3716          * text was for VT100, and not updated for VT420.
 3717          */
 3718         resetRendition(xw);
 3719         resetMargins(xw);
 3720         CursorSet(screen, 0, 0, xw->flags);
 3721         xtermParseRect(xw, 0, 0, &myRect);
 3722         ScrnFillRectangle(xw, &myRect, 'E', 0, False);
 3723         ResetState(sp);
 3724         break;
 3725 
 3726     case CASE_GSETS5:
 3727         if (screen->vtXX_level < 5) {
 3728         ResetState(sp);
 3729         break;
 3730         }
 3731         /* FALLTHRU */
 3732     case CASE_GSETS3:
 3733         if (screen->vtXX_level < 3) {
 3734         ResetState(sp);
 3735         break;
 3736         }
 3737         /* FALLTHRU */
 3738     case CASE_GSETS:
 3739         if (screen->vtXX_level >= 2 || strchr("012AB", (int) c) != 0) {
 3740         TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
 3741         xtermDecodeSCS(xw, sp->scstype, 0, (int) c);
 3742         }
 3743         ResetState(sp);
 3744         break;
 3745 
 3746     case CASE_ANSI_SC:
 3747         if (IsLeftRightMode(xw)) {
 3748         int left;
 3749         int right;
 3750 
 3751         TRACE(("CASE_DECSLRM - set left and right margin\n"));
 3752         left = one_if_default(0);
 3753         if (nparam < 2 || (right = GetParam(1)) == DEFAULT
 3754             || right > MaxCols(screen)
 3755             || right == 0)
 3756             right = MaxCols(screen);
 3757         if (right > left) {
 3758             set_lr_margins(screen, left - 1, right - 1);
 3759             CursorSet(screen, 0, 0, xw->flags);
 3760         }
 3761         } else {
 3762         TRACE(("CASE_ANSI_SC - save cursor\n"));
 3763         CursorSave(xw);
 3764         }
 3765         ResetState(sp);
 3766         break;
 3767 
 3768     case CASE_DECSC:
 3769         TRACE(("CASE_DECSC - save cursor\n"));
 3770         CursorSave(xw);
 3771         ResetState(sp);
 3772         break;
 3773 
 3774     case CASE_ANSI_RC:
 3775         /* FALLTHRU */
 3776     case CASE_DECRC:
 3777         TRACE(("CASE_%sRC - restore cursor\n",
 3778            (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_"));
 3779         CursorRestore(xw);
 3780         if_OPT_ISO_COLORS(screen, {
 3781         setExtendedFG(xw);
 3782         });
 3783         ResetState(sp);
 3784         break;
 3785 
 3786     case CASE_DECKPAM:
 3787         TRACE(("CASE_DECKPAM\n"));
 3788         xw->keyboard.flags |= MODE_DECKPAM;
 3789         update_appkeypad();
 3790         ResetState(sp);
 3791         break;
 3792 
 3793     case CASE_DECKPNM:
 3794         TRACE(("CASE_DECKPNM\n"));
 3795         UIntClr(xw->keyboard.flags, MODE_DECKPAM);
 3796         update_appkeypad();
 3797         ResetState(sp);
 3798         break;
 3799 
 3800     case CASE_CSI_QUOTE_STATE:
 3801         sp->parsestate = csi_quo_table;
 3802         break;
 3803 
 3804 #if OPT_BLINK_CURS
 3805     case CASE_CSI_SPACE_STATE:
 3806         sp->parsestate = csi_sp_table;
 3807         break;
 3808 
 3809     case CASE_DECSCUSR:
 3810         TRACE(("CASE_DECSCUSR\n"));
 3811         {
 3812         Boolean change = True;
 3813         int blinks = screen->cursor_blink_esc;
 3814 
 3815         HideCursor();
 3816 
 3817         switch (GetParam(0)) {
 3818         case DEFAULT:
 3819             /* FALLTHRU */
 3820         case DEFAULT_STYLE:
 3821             /* FALLTHRU */
 3822         case BLINK_BLOCK:
 3823             blinks = True;
 3824             screen->cursor_shape = CURSOR_BLOCK;
 3825             break;
 3826         case STEADY_BLOCK:
 3827             blinks = False;
 3828             screen->cursor_shape = CURSOR_BLOCK;
 3829             break;
 3830         case BLINK_UNDERLINE:
 3831             blinks = True;
 3832             screen->cursor_shape = CURSOR_UNDERLINE;
 3833             break;
 3834         case STEADY_UNDERLINE:
 3835             blinks = False;
 3836             screen->cursor_shape = CURSOR_UNDERLINE;
 3837             break;
 3838         case BLINK_BAR:
 3839             blinks = True;
 3840             screen->cursor_shape = CURSOR_BAR;
 3841             break;
 3842         case STEADY_BAR:
 3843             blinks = False;
 3844             screen->cursor_shape = CURSOR_BAR;
 3845             break;
 3846         default:
 3847             change = False;
 3848             break;
 3849         }
 3850         TRACE(("cursor_shape:%d blinks:%s\n",
 3851                screen->cursor_shape, BtoS(blinks)));
 3852         if (change) {
 3853             xtermSetCursorBox(screen);
 3854             screen->cursor_blink_esc = blinks;
 3855             UpdateCursorBlink(xw);
 3856         }
 3857         }
 3858         ResetState(sp);
 3859         break;
 3860 #endif
 3861 
 3862 #if OPT_SCROLL_LOCK
 3863     case CASE_DECLL:
 3864         TRACE(("CASE_DECLL\n"));
 3865         if (nparam > 0) {
 3866         for (count = 0; count < nparam; ++count) {
 3867             int op = zero_if_default(count);
 3868             switch (op) {
 3869             case 0:
 3870             case DEFAULT:
 3871             xtermClearLEDs(screen);
 3872             break;
 3873             case 1:
 3874             /* FALLTHRU */
 3875             case 2:
 3876             /* FALLTHRU */
 3877             case 3:
 3878             xtermShowLED(screen,
 3879                      (Cardinal) op,
 3880                      True);
 3881             break;
 3882             case 21:
 3883             /* FALLTHRU */
 3884             case 22:
 3885             /* FALLTHRU */
 3886             case 23:
 3887             xtermShowLED(screen,
 3888                      (Cardinal) (op - 20),
 3889                      True);
 3890             break;
 3891             }
 3892         }
 3893         } else {
 3894         xtermClearLEDs(screen);
 3895         }
 3896         ResetState(sp);
 3897         break;
 3898 #endif
 3899 
 3900 #if OPT_VT52_MODE
 3901     case CASE_VT52_FINISH:
 3902         TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",
 3903            screen->terminal_id,
 3904            screen->vtXX_level));
 3905         if (screen->terminal_id >= 100
 3906         && screen->vtXX_level == 0) {
 3907         sp->groundtable =
 3908             sp->parsestate = ansi_table;
 3909         /*
 3910          * On restore, the terminal does not recognize DECRQSS for
 3911          * DECSCL (per vttest).
 3912          */
 3913         screen->vtXX_level = 1;
 3914         xw->flags = screen->vt52_save_flags;
 3915         screen->curgl = screen->vt52_save_curgl;
 3916         screen->curgr = screen->vt52_save_curgr;
 3917         screen->curss = screen->vt52_save_curss;
 3918         restoreCharsets(screen, screen->vt52_save_gsets);
 3919         update_vt52_vt100_settings();
 3920         }
 3921         break;
 3922 #endif
 3923 
 3924     case CASE_ANSI_LEVEL_1:
 3925         TRACE(("CASE_ANSI_LEVEL_1\n"));
 3926         set_ansi_conformance(screen, 1);
 3927         ResetState(sp);
 3928         break;
 3929 
 3930     case CASE_ANSI_LEVEL_2:
 3931         TRACE(("CASE_ANSI_LEVEL_2\n"));
 3932         set_ansi_conformance(screen, 2);
 3933         ResetState(sp);
 3934         break;
 3935 
 3936     case CASE_ANSI_LEVEL_3:
 3937         TRACE(("CASE_ANSI_LEVEL_3\n"));
 3938         set_ansi_conformance(screen, 3);
 3939         ResetState(sp);
 3940         break;
 3941 
 3942     case CASE_DECSCL:
 3943         TRACE(("CASE_DECSCL(%d,%d)\n", GetParam(0), GetParam(1)));
 3944         /*
 3945          * This changes the emulation level, and is not recognized by
 3946          * VT100s.  However, a VT220 or above can be set to conformance
 3947          * level 1 to act like a VT100.
 3948          */
 3949         if (screen->terminal_id >= 200) {
 3950         /*
 3951          * Disallow unrecognized parameters, as well as attempts to set
 3952          * the operating level higher than the given terminal-id.
 3953          */
 3954         if (GetParam(0) >= 61
 3955             && GetParam(0) <= 60 + (screen->terminal_id / 100)) {
 3956             int new_vtXX_level = GetParam(0) - 60;
 3957             int case_value = zero_if_default(1);
 3958             /*
 3959              * Note:
 3960              *
 3961              * The VT300, VT420, VT520 manuals claim that DECSCL does a
 3962              * hard reset (RIS).
 3963              *
 3964              * Both the VT220 manual and DEC STD 070 (which documents
 3965              * levels 1-4 in detail) state that it is a soft reset.
 3966              *
 3967              * Perhaps both sets of manuals are right (unlikely). 
 3968              * Kermit says it's soft.
 3969              */
 3970             ReallyReset(xw, False, False);
 3971             init_parser(xw, sp);
 3972             screen->vtXX_level = new_vtXX_level;
 3973             if (new_vtXX_level > 1) {
 3974             switch (case_value) {
 3975             case 1:
 3976                 show_8bit_control(False);
 3977                 break;
 3978             case 0:
 3979             case 2:
 3980                 show_8bit_control(True);
 3981                 break;
 3982             }
 3983             }
 3984         }
 3985         }
 3986         ResetState(sp);
 3987         break;
 3988 
 3989     case CASE_DECSCA:
 3990         TRACE(("CASE_DECSCA\n"));
 3991         screen->protected_mode = DEC_PROTECT;
 3992         if (GetParam(0) <= 0 || GetParam(0) == 2) {
 3993         UIntClr(xw->flags, PROTECTED);
 3994         TRACE(("...clear PROTECTED\n"));
 3995         } else if (GetParam(0) == 1) {
 3996         xw->flags |= PROTECTED;
 3997         TRACE(("...set PROTECTED\n"));
 3998         }
 3999         ResetState(sp);
 4000         break;
 4001 
 4002     case CASE_DECSED:
 4003         TRACE(("CASE_DECSED\n"));
 4004         do_erase_display(xw, zero_if_default(0), DEC_PROTECT);
 4005         ResetState(sp);
 4006         break;
 4007 
 4008     case CASE_DECSEL:
 4009         TRACE(("CASE_DECSEL\n"));
 4010         do_erase_line(xw, zero_if_default(0), DEC_PROTECT);
 4011         ResetState(sp);
 4012         break;
 4013 
 4014     case CASE_GRAPHICS_ATTRIBUTES:
 4015 #if OPT_GRAPHICS
 4016         TRACE(("CASE_GRAPHICS_ATTRIBUTES\n"));
 4017         {
 4018         /* request: item, action, value */
 4019         /* reply: item, status, value */
 4020         if (nparam != 3) {
 4021             TRACE(("DATA_ERROR: malformed CASE_GRAPHICS_ATTRIBUTES request with %d parameters\n", nparam));
 4022         } else {
 4023             int status = 3; /* assume failure */
 4024             int result = 0;
 4025             int result2 = 0;
 4026 
 4027             TRACE(("CASE_GRAPHICS_ATTRIBUTES request: %d, %d, %d\n",
 4028                GetParam(0), GetParam(1), GetParam(2)));
 4029             switch (GetParam(0)) {
 4030             case 1: /* color register count */
 4031             switch (GetParam(1)) {
 4032             case 1: /* read */
 4033                 status = 0;     /* success */
 4034                 result = (int) get_color_register_count(screen);
 4035                 break;
 4036             case 2: /* reset */
 4037                 screen->numcolorregisters = 0;
 4038                 status = 0;     /* success */
 4039                 result = (int) get_color_register_count(screen);
 4040                 break;
 4041             case 3: /* set */
 4042                 if (GetParam(2) > 1 &&
 4043                 (unsigned) GetParam(2) <= MAX_COLOR_REGISTERS) {
 4044                 screen->numcolorregisters = GetParam(2);
 4045                 status = 0; /* success */
 4046                 result = (int) get_color_register_count(screen);
 4047                 }
 4048                 break;
 4049             case 4: /* read maximum */
 4050                 status = 0;     /* success */
 4051                 result = MAX_COLOR_REGISTERS;
 4052                 break;
 4053             default:
 4054                 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES color register count request with unknown action parameter: %d\n",
 4055                    GetParam(1)));
 4056                 status = 2;     /* error in Pa */
 4057                 break;
 4058             }
 4059             break;
 4060             case 2: /* graphics geometry */
 4061             switch (GetParam(1)) {
 4062             case 1: /* read */
 4063                 TRACE(("Get sixel graphics geometry\n"));
 4064                 status = 0;     /* success */
 4065                 result = Min(Width(screen), screen->graphics_max_wide);
 4066                 result2 = Min(Height(screen), screen->graphics_max_high);
 4067                 break;
 4068             case 2: /* reset */
 4069                 /* FALLTHRU */
 4070             case 3: /* set */
 4071                 break;
 4072             case 4: /* read maximum */
 4073                 status = 0;     /* success */
 4074                 result = screen->graphics_max_wide;
 4075                 result2 = screen->graphics_max_high;
 4076                 break;
 4077             default:
 4078                 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES graphics geometry request with unknown action parameter: %d\n",
 4079                    GetParam(1)));
 4080                 status = 2;     /* error in Pa */
 4081                 break;
 4082             }
 4083             break;
 4084 # if OPT_REGIS_GRAPHICS
 4085             case 3: /* ReGIS geometry */
 4086             switch (GetParam(1)) {
 4087             case 1: /* read */
 4088                 status = 0;     /* success */
 4089                 result = screen->graphics_regis_def_wide;
 4090                 result2 = screen->graphics_regis_def_high;
 4091                 break;
 4092             case 2: /* reset */
 4093                 /* FALLTHRU */
 4094             case 3: /* set */
 4095                 /* FALLTHRU */
 4096             case 4: /* read maximum */
 4097                 /* not implemented */
 4098                 break;
 4099             default:
 4100                 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES ReGIS geometry request with unknown action parameter: %d\n",
 4101                    GetParam(1)));
 4102                 status = 2;     /* error in Pa */
 4103                 break;
 4104             }
 4105             break;
 4106 #endif
 4107             default:
 4108             TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES request with unknown item parameter: %d\n",
 4109                    GetParam(0)));
 4110             status = 1;
 4111             break;
 4112             }
 4113 
 4114             init_reply(ANSI_CSI);
 4115             reply.a_pintro = '?';
 4116             count = 0;
 4117             reply.a_param[count++] = (ParmType) GetParam(0);
 4118             reply.a_param[count++] = (ParmType) status;
 4119             reply.a_param[count++] = (ParmType) result;
 4120             if (GetParam(0) >= 2)
 4121             reply.a_param[count++] = (ParmType) result2;
 4122             reply.a_nparam = (ParmType) count;
 4123             reply.a_inters = 0;
 4124             reply.a_final = 'S';
 4125             unparseseq(xw, &reply);
 4126         }
 4127         }
 4128 #endif
 4129         ResetState(sp);
 4130         break;
 4131 
 4132     case CASE_ST:
 4133         TRACE(("CASE_ST: End of String (%lu bytes) (mode=%d)\n",
 4134            (unsigned long) sp->string_used,
 4135            sp->string_mode));
 4136         ResetState(sp);
 4137         if (!sp->string_used)
 4138         break;
 4139         sp->string_area[--(sp->string_used)] = '\0';
 4140         switch (sp->string_mode) {
 4141         case ANSI_APC:
 4142         /* ignored */
 4143         break;
 4144         case ANSI_DCS:
 4145         do_dcs(xw, sp->string_area, sp->string_used);
 4146         break;
 4147         case ANSI_OSC:
 4148         do_osc(xw, sp->string_area, sp->string_used, ANSI_ST);
 4149         break;
 4150         case ANSI_PM:
 4151         /* ignored */
 4152         break;
 4153         case ANSI_SOS:
 4154         /* ignored */
 4155         break;
 4156         default:
 4157         TRACE(("unknown mode\n"));
 4158         break;
 4159         }
 4160         break;
 4161 
 4162     case CASE_SOS:
 4163         TRACE(("CASE_SOS: Start of String\n"));
 4164         if (ParseSOS(screen)) {
 4165         sp->string_mode = ANSI_SOS;
 4166         sp->parsestate = sos_table;
 4167         } else {
 4168         illegal_parse(xw, c, sp);
 4169         }
 4170         break;
 4171 
 4172     case CASE_PM:
 4173         TRACE(("CASE_PM: Privacy Message\n"));
 4174         if (ParseSOS(screen)) {
 4175         sp->string_mode = ANSI_PM;
 4176         sp->parsestate = sos_table;
 4177         } else {
 4178         illegal_parse(xw, c, sp);
 4179         }
 4180         break;
 4181 
 4182     case CASE_DCS:
 4183         TRACE(("CASE_DCS: Device Control String\n"));
 4184         sp->string_mode = ANSI_DCS;
 4185         sp->parsestate = sos_table;
 4186         break;
 4187 
 4188     case CASE_APC:
 4189         TRACE(("CASE_APC: Application Program Command\n"));
 4190         if (ParseSOS(screen)) {
 4191         sp->string_mode = ANSI_APC;
 4192         sp->parsestate = sos_table;
 4193         } else {
 4194         illegal_parse(xw, c, sp);
 4195         }
 4196         break;
 4197 
 4198     case CASE_SPA:
 4199         TRACE(("CASE_SPA - start protected area\n"));
 4200         screen->protected_mode = ISO_PROTECT;
 4201         xw->flags |= PROTECTED;
 4202         ResetState(sp);
 4203         break;
 4204 
 4205     case CASE_EPA:
 4206         TRACE(("CASE_EPA - end protected area\n"));
 4207         UIntClr(xw->flags, PROTECTED);
 4208         ResetState(sp);
 4209         break;
 4210 
 4211     case CASE_SU:
 4212         TRACE(("CASE_SU - scroll up\n"));
 4213         xtermScroll(xw, one_if_default(0));
 4214         ResetState(sp);
 4215         break;
 4216 
 4217     case CASE_SL:       /* ISO 6429, non-DEC */
 4218         TRACE(("CASE_SL - scroll left\n"));
 4219         xtermScrollLR(xw, one_if_default(0), True);
 4220         ResetState(sp);
 4221         break;
 4222 
 4223     case CASE_SR:       /* ISO 6429, non-DEC */
 4224         TRACE(("CASE_SR - scroll right\n"));
 4225         xtermScrollLR(xw, one_if_default(0), False);
 4226         ResetState(sp);
 4227         break;
 4228 
 4229     case CASE_DECDC:
 4230         TRACE(("CASE_DC - delete column\n"));
 4231         if (screen->vtXX_level >= 4) {
 4232         xtermColScroll(xw, one_if_default(0), True, screen->cur_col);
 4233         }
 4234         ResetState(sp);
 4235         break;
 4236 
 4237     case CASE_DECIC:
 4238         TRACE(("CASE_IC - insert column\n"));
 4239         if (screen->vtXX_level >= 4) {
 4240         xtermColScroll(xw, one_if_default(0), False, screen->cur_col);
 4241         }
 4242         ResetState(sp);
 4243         break;
 4244 
 4245     case CASE_DECBI:
 4246         TRACE(("CASE_BI - back index\n"));
 4247         if (screen->vtXX_level >= 4) {
 4248         xtermColIndex(xw, True);
 4249         }
 4250         ResetState(sp);
 4251         break;
 4252 
 4253     case CASE_DECFI:
 4254         TRACE(("CASE_FI - forward index\n"));
 4255         if (screen->vtXX_level >= 4) {
 4256         xtermColIndex(xw, False);
 4257         }
 4258         ResetState(sp);
 4259         break;
 4260 
 4261     case CASE_IND:
 4262         TRACE(("CASE_IND - index\n"));
 4263         xtermIndex(xw, 1);
 4264         do_xevents(xw);
 4265         ResetState(sp);
 4266         break;
 4267 
 4268     case CASE_CPL:
 4269         TRACE(("CASE_CPL - cursor prev line\n"));
 4270         CursorPrevLine(xw, one_if_default(0));
 4271         ResetState(sp);
 4272         break;
 4273 
 4274     case CASE_CNL:
 4275         TRACE(("CASE_CNL - cursor next line\n"));
 4276         CursorNextLine(xw, one_if_default(0));
 4277         ResetState(sp);
 4278         break;
 4279 
 4280     case CASE_NEL:
 4281         TRACE(("CASE_NEL\n"));
 4282         xtermIndex(xw, 1);
 4283         CarriageReturn(xw);
 4284         ResetState(sp);
 4285         break;
 4286 
 4287     case CASE_HTS:
 4288         TRACE(("CASE_HTS - horizontal tab set\n"));
 4289         TabSet(xw->tabs, screen->cur_col);
 4290         ResetState(sp);
 4291         break;
 4292 
 4293     case CASE_REPORT_VERSION:
 4294         TRACE(("CASE_REPORT_VERSION - report terminal version\n"));
 4295         if (GetParam(0) <= 0) {
 4296         unparseputc1(xw, ANSI_DCS);
 4297         unparseputc(xw, '>');
 4298         unparseputc(xw, '|');
 4299         unparseputs(xw, xtermVersion());
 4300         unparseputc1(xw, ANSI_ST);
 4301         unparse_end(xw);
 4302         }
 4303         ResetState(sp);
 4304         break;
 4305 
 4306     case CASE_RI:
 4307         TRACE(("CASE_RI - reverse index\n"));
 4308         RevIndex(xw, 1);
 4309         ResetState(sp);
 4310         break;
 4311 
 4312     case CASE_SS2:
 4313         TRACE(("CASE_SS2\n"));
 4314         screen->curss = 2;
 4315         ResetState(sp);
 4316         break;
 4317 
 4318     case CASE_SS3:
 4319         TRACE(("CASE_SS3\n"));
 4320         screen->curss = 3;
 4321         ResetState(sp);
 4322         break;
 4323 
 4324     case CASE_CSI_STATE:
 4325         /* enter csi state */
 4326         InitParams();
 4327         SetParam(nparam++, DEFAULT);
 4328         sp->parsestate = csi_table;
 4329         break;
 4330 
 4331     case CASE_ESC_SP_STATE:
 4332         /* esc space */
 4333         sp->parsestate = esc_sp_table;
 4334         break;
 4335 
 4336     case CASE_CSI_EX_STATE:
 4337         /* csi exclamation */
 4338         sp->parsestate = csi_ex_table;
 4339         break;
 4340 
 4341     case CASE_CSI_TICK_STATE:
 4342         /* csi tick (') */
 4343         sp->parsestate = csi_tick_table;
 4344         break;
 4345 
 4346 #if OPT_DEC_LOCATOR
 4347     case CASE_DECEFR:
 4348         TRACE(("CASE_DECEFR - Enable Filter Rectangle\n"));
 4349         if (okSendMousePos(xw) == DEC_LOCATOR) {
 4350         MotionOff(screen, xw);
 4351         if ((screen->loc_filter_top = GetParam(0)) < 1)
 4352             screen->loc_filter_top = LOC_FILTER_POS;
 4353         if (nparam < 2
 4354             || (screen->loc_filter_left = GetParam(1)) < 1)
 4355             screen->loc_filter_left = LOC_FILTER_POS;
 4356         if (nparam < 3
 4357             || (screen->loc_filter_bottom = GetParam(2)) < 1)
 4358             screen->loc_filter_bottom = LOC_FILTER_POS;
 4359         if (nparam < 4
 4360             || (screen->loc_filter_right = GetParam(3)) < 1)
 4361             screen->loc_filter_right = LOC_FILTER_POS;
 4362         InitLocatorFilter(xw);
 4363         }
 4364         ResetState(sp);
 4365         break;
 4366 
 4367     case CASE_DECELR:
 4368         MotionOff(screen, xw);
 4369         if (GetParam(0) <= 0 || GetParam(0) > 2) {
 4370         screen->send_mouse_pos = MOUSE_OFF;
 4371         TRACE(("DECELR - Disable Locator Reports\n"));
 4372         } else {
 4373         TRACE(("DECELR - Enable Locator Reports\n"));
 4374         screen->send_mouse_pos = DEC_LOCATOR;
 4375         xtermShowPointer(xw, True);
 4376         if (GetParam(0) == 2) {
 4377             screen->locator_reset = True;
 4378         } else {
 4379             screen->locator_reset = False;
 4380         }
 4381         if (nparam < 2 || GetParam(1) != 1) {
 4382             screen->locator_pixels = False;
 4383         } else {
 4384             screen->locator_pixels = True;
 4385         }
 4386         screen->loc_filter = False;
 4387         }
 4388         ResetState(sp);
 4389         break;
 4390 
 4391     case CASE_DECSLE:
 4392         TRACE(("DECSLE - Select Locator Events\n"));
 4393         for (count = 0; count < nparam; ++count) {
 4394         switch (zero_if_default(count)) {
 4395         case 0:
 4396             MotionOff(screen, xw);
 4397             screen->loc_filter = False;
 4398             screen->locator_events = 0;
 4399             break;
 4400         case 1:
 4401             screen->locator_events |= LOC_BTNS_DN;
 4402             break;
 4403         case 2:
 4404             UIntClr(screen->locator_events, LOC_BTNS_DN);
 4405             break;
 4406         case 3:
 4407             screen->locator_events |= LOC_BTNS_UP;
 4408             break;
 4409         case 4:
 4410             UIntClr(screen->locator_events, LOC_BTNS_UP);
 4411             break;
 4412         }
 4413         }
 4414         ResetState(sp);
 4415         break;
 4416 
 4417     case CASE_DECRQLP:
 4418         TRACE(("DECRQLP - Request Locator Position\n"));
 4419         if (GetParam(0) < 2) {
 4420         /* Issue DECLRP Locator Position Report */
 4421         GetLocatorPosition(xw);
 4422         }
 4423         ResetState(sp);
 4424         break;
 4425 #endif /* OPT_DEC_LOCATOR */
 4426 
 4427 #if OPT_DEC_RECTOPS
 4428     case CASE_CSI_DOLLAR_STATE:
 4429         TRACE(("CASE_CSI_DOLLAR_STATE\n"));
 4430         /* csi dollar ($) */
 4431         if (screen->vtXX_level >= 3)
 4432         sp->parsestate = csi_dollar_table;
 4433         else
 4434         sp->parsestate = eigtable;
 4435         break;
 4436 
 4437     case CASE_CSI_STAR_STATE:
 4438         TRACE(("CASE_CSI_STAR_STATE\n"));
 4439         /* csi star (*) */
 4440         if (screen->vtXX_level >= 4)
 4441         sp->parsestate = csi_star_table;
 4442         else
 4443         sp->parsestate = eigtable;
 4444         break;
 4445 
 4446     case CASE_DECRQCRA:
 4447         if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewGetChecksum)) {
 4448         int checksum;
 4449         int pid;
 4450 
 4451         TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n"));
 4452         xtermCheckRect(xw, ParamPair(0), &checksum);
 4453         init_reply(ANSI_DCS);
 4454         count = 0;
 4455         checksum &= 0xffff;
 4456         pid = GetParam(0);
 4457         reply.a_param[count++] = (ParmType) pid;
 4458         reply.a_delim = "!~";   /* delimiter */
 4459         reply.a_radix[count] = 16;
 4460         reply.a_param[count++] = (ParmType) checksum;
 4461         reply.a_nparam = (ParmType) count;
 4462         TRACE(("...checksum(%d) = %04X\n", pid, checksum));
 4463         unparseseq(xw, &reply);
 4464         }
 4465         ResetState(sp);
 4466         break;
 4467 
 4468     case CASE_DECCRA:
 4469         if (screen->vtXX_level >= 4) {
 4470         TRACE(("CASE_DECCRA - Copy rectangular area\n"));
 4471         xtermParseRect(xw, ParamPair(0), &myRect);
 4472         ScrnCopyRectangle(xw, &myRect, ParamPair(5));
 4473         }
 4474         ResetState(sp);
 4475         break;
 4476 
 4477     case CASE_DECERA:
 4478         if (screen->vtXX_level >= 4) {
 4479         TRACE(("CASE_DECERA - Erase rectangular area\n"));
 4480         xtermParseRect(xw, ParamPair(0), &myRect);
 4481         ScrnFillRectangle(xw, &myRect, ' ', 0, True);
 4482         }
 4483         ResetState(sp);
 4484         break;
 4485 
 4486     case CASE_DECFRA:
 4487         if (screen->vtXX_level >= 4) {
 4488         value = zero_if_default(0);
 4489 
 4490         TRACE(("CASE_DECFRA - Fill rectangular area\n"));
 4491         if (nparam > 0 && IsLatin1(value)) {
 4492             xtermParseRect(xw, ParamPair(1), &myRect);
 4493             ScrnFillRectangle(xw, &myRect, value, xw->flags, True);
 4494         }
 4495         }
 4496         ResetState(sp);
 4497         break;
 4498 
 4499     case CASE_DECSERA:
 4500         if (screen->vtXX_level >= 4) {
 4501         TRACE(("CASE_DECSERA - Selective erase rectangular area\n"));
 4502         xtermParseRect(xw, ParamPair(0), &myRect);
 4503         ScrnWipeRectangle(xw, &myRect);
 4504         }
 4505         ResetState(sp);
 4506         break;
 4507 
 4508     case CASE_DECSACE:
 4509         TRACE(("CASE_DECSACE - Select attribute change extent\n"));
 4510         screen->cur_decsace = zero_if_default(0);
 4511         ResetState(sp);
 4512         break;
 4513 
 4514     case CASE_DECCARA:
 4515         if (screen->vtXX_level >= 4) {
 4516         TRACE(("CASE_DECCARA - Change attributes in rectangular area\n"));
 4517         xtermParseRect(xw, ParamPair(0), &myRect);
 4518         ScrnMarkRectangle(xw, &myRect, False, ParamPair(4));
 4519         }
 4520         ResetState(sp);
 4521         break;
 4522 
 4523     case CASE_DECRARA:
 4524         if (screen->vtXX_level >= 4) {
 4525         TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n"));
 4526         xtermParseRect(xw, ParamPair(0), &myRect);
 4527         ScrnMarkRectangle(xw, &myRect, True, ParamPair(4));
 4528         }
 4529         ResetState(sp);
 4530         break;
 4531 
 4532     case CASE_DECSCPP:
 4533         if (screen->vtXX_level >= 3) {
 4534         TRACE(("CASE_DECSCPP\n"));
 4535         /* default and 0 are "80", with "132" as the other legal choice */
 4536         switch (zero_if_default(0)) {
 4537         case 0:
 4538         case 80:
 4539             value = 80;
 4540             break;
 4541         case 132:
 4542             value = 132;
 4543             break;
 4544         default:
 4545             value = -1;
 4546             break;
 4547         }
 4548         if (value > 0) {
 4549             if (screen->cur_col + 1 > value)
 4550             CursorSet(screen, screen->cur_row, value - 1, xw->flags);
 4551             UIntClr(xw->flags, IN132COLUMNS);
 4552             if (value == 132)
 4553             UIntSet(xw->flags, IN132COLUMNS);
 4554             RequestResize(xw, -1, value, True);
 4555         }
 4556         }
 4557         ResetState(sp);
 4558         break;
 4559 
 4560     case CASE_DECSNLS:
 4561         if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewSetWinLines)) {
 4562         TRACE(("CASE_DECSNLS\n"));
 4563         value = zero_if_default(0);
 4564         if (value >= 1 && value <= 255) {
 4565             RequestResize(xw, value, -1, True);
 4566         }
 4567         }
 4568         ResetState(sp);
 4569         break;
 4570 
 4571     case CASE_DECRQPSR:
 4572 #define reply_char(n,c) do { reply.a_radix[(n)] = 1; reply.a_param[(n)++] = (ParmType)(c); } while (0)
 4573 #define reply_bit(n,c) ((n) ? (c) : 0)
 4574         if (screen->vtXX_level >= 3) {
 4575         TRACE(("CASE_DECRQPSR\n"));
 4576         switch (GetParam(0)) {
 4577         case 1:
 4578             TRACE(("...DECCIR\n"));
 4579             init_reply(ANSI_DCS);
 4580             count = 0;
 4581             reply_char(count, '1');
 4582             reply_char(count, '$');
 4583             reply_char(count, 'u');
 4584             reply.a_param[count++] = (ParmType) (screen->cur_row + 1);
 4585             reply.a_param[count++] = (ParmType) (screen->cur_col + 1);
 4586             reply.a_param[count++] = (ParmType) thispage;
 4587             reply_char(count, ';');
 4588             reply_char(count, (0x40
 4589                        | reply_bit(xw->flags & INVERSE, 8)
 4590                        | reply_bit(xw->flags & BLINK, 4)
 4591                        | reply_bit(xw->flags & UNDERLINE, 2)
 4592                        | reply_bit(xw->flags & BOLD, 1)
 4593                    ));
 4594             reply_char(count, ';');
 4595             reply_char(count, 0x40 |
 4596                    reply_bit(screen->protected_mode &
 4597                      DEC_PROTECT, 1)
 4598             );
 4599             reply_char(count, ';');
 4600             reply_char(count, (0x40
 4601                        | reply_bit(screen->do_wrap, 8)
 4602                        | reply_bit((screen->curss == 3), 4)
 4603                        | reply_bit((screen->curss == 2), 2)
 4604                        | reply_bit(xw->flags & ORIGIN, 1)
 4605                    ));
 4606             reply_char(count, ';');
 4607             reply.a_param[count++] = screen->curgl;
 4608             reply.a_param[count++] = screen->curgr;
 4609             reply_char(count, ';');
 4610             reply_char(count, 0x4f);    /* assert all 96's */
 4611             reply_char(count, ';');
 4612             for (item = 0; item < NUM_GSETS; ++item) {
 4613             char *temp = encode_scs(screen->gsets[item]);
 4614             while (*temp != '\0') {
 4615                 reply_char(count, *temp++);
 4616             }
 4617             }
 4618             reply.a_nparam = (ParmType) count;
 4619             unparseseq(xw, &reply);
 4620             break;
 4621         case 2:
 4622             TRACE(("...DECTABSR\n"));
 4623             init_reply(ANSI_DCS);
 4624             reply.a_delim = "/";
 4625             count = 0;
 4626             reply_char(count, '2');
 4627             reply_char(count, '$');
 4628             reply_char(count, 'u');
 4629             for (item = 0; item < MAX_TABS; ++item) {
 4630             if (count + 1 >= NPARAM)
 4631                 break;
 4632             if (TabIsSet(xw->tabs, item)) {
 4633                 reply.a_param[count++] = (ParmType) (item + 1);
 4634             }
 4635             if (item > screen->max_col)
 4636                 break;
 4637             }
 4638             reply.a_nparam = (ParmType) count;
 4639             unparseseq(xw, &reply);
 4640             break;
 4641         }
 4642         }
 4643         ResetState(sp);
 4644         break;
 4645 
 4646     case CASE_RQM:
 4647         TRACE(("CASE_RQM\n"));
 4648         do_ansi_rqm(xw, ParamPair(0));
 4649         ResetState(sp);
 4650         break;
 4651 
 4652     case CASE_DECRQM:
 4653         TRACE(("CASE_DECRQM\n"));
 4654         do_dec_rqm(xw, ParamPair(0));
 4655         ResetState(sp);
 4656         break;
 4657 
 4658     case CASE_CSI_DEC_DOLLAR_STATE:
 4659         TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n"));
 4660         /* csi ? dollar ($) */
 4661         sp->parsestate = csi_dec_dollar_table;
 4662         break;
 4663 #else
 4664     case CASE_CSI_DOLLAR_STATE:
 4665         /* csi dollar ($) */
 4666         sp->parsestate = eigtable;
 4667         break;
 4668 
 4669     case CASE_CSI_STAR_STATE:
 4670         /* csi dollar (*) */
 4671         sp->parsestate = eigtable;
 4672         break;
 4673 
 4674     case CASE_CSI_DEC_DOLLAR_STATE:
 4675         /* csi ? dollar ($) */
 4676         sp->parsestate = eigtable;
 4677         break;
 4678 #endif /* OPT_DEC_RECTOPS */
 4679 
 4680 #if OPT_XTERM_SGR
 4681     case CASE_CSI_HASH_STATE:
 4682         TRACE(("CASE_CSI_HASH_STATE\n"));
 4683         /* csi hash (#) */
 4684         sp->parsestate = csi_hash_table;
 4685         break;
 4686 
 4687     case CASE_XTERM_CHECKSUM:
 4688 #if OPT_DEC_RECTOPS
 4689         if (screen->vtXX_level >= 4 && AllowWindowOps(xw, ewSetChecksum)) {
 4690         TRACE(("CASE_XTERM_CHECKSUM\n"));
 4691         screen->checksum_ext = zero_if_default(0);
 4692         }
 4693 #endif
 4694         ResetState(sp);
 4695         break;
 4696 
 4697     case CASE_XTERM_PUSH_SGR:
 4698         TRACE(("CASE_XTERM_PUSH_SGR\n"));
 4699         value = 0;
 4700         if (nparam == 0 || (nparam == 1 && GetParam(0) == DEFAULT)) {
 4701         value = DEFAULT;
 4702         } else if (nparam > 0) {
 4703         for (count = 0; count < nparam; ++count) {
 4704             item = zero_if_default(count);
 4705             if (item > 0 && item < MAX_PUSH_SGR) {
 4706             value |= (1 << (item - 1));
 4707             }
 4708         }
 4709         }
 4710         xtermPushSGR(xw, value);
 4711         ResetState(sp);
 4712         break;
 4713 
 4714     case CASE_XTERM_REPORT_SGR:
 4715         TRACE(("CASE_XTERM_REPORT_SGR\n"));
 4716         xtermParseRect(xw, ParamPair(0), &myRect);
 4717         xtermReportSGR(xw, &myRect);
 4718         ResetState(sp);
 4719         break;
 4720 
 4721     case CASE_XTERM_POP_SGR:
 4722         TRACE(("CASE_XTERM_POP_SGR\n"));
 4723         xtermPopSGR(xw);
 4724         ResetState(sp);
 4725         break;
 4726 #endif
 4727 
 4728     case CASE_S7C1T:
 4729         TRACE(("CASE_S7C1T\n"));
 4730         if (screen->vtXX_level >= 2) {
 4731         show_8bit_control(False);
 4732         ResetState(sp);
 4733         }
 4734         break;
 4735 
 4736     case CASE_S8C1T:
 4737         TRACE(("CASE_S8C1T\n"));
 4738         if (screen->vtXX_level >= 2) {
 4739         show_8bit_control(True);
 4740         ResetState(sp);
 4741         }
 4742         break;
 4743 
 4744     case CASE_OSC:
 4745         TRACE(("CASE_OSC: Operating System Command\n"));
 4746         sp->parsestate = sos_table;
 4747         sp->string_mode = ANSI_OSC;
 4748         break;
 4749 
 4750     case CASE_RIS:
 4751         TRACE(("CASE_RIS\n"));
 4752         VTReset(xw, True, True);
 4753         /* NOTREACHED */
 4754 
 4755     case CASE_DECSTR:
 4756         TRACE(("CASE_DECSTR\n"));
 4757         VTReset(xw, False, False);
 4758         /* NOTREACHED */
 4759 
 4760     case CASE_REP:
 4761         TRACE(("CASE_REP\n"));
 4762         if (sp->lastchar >= 0 &&
 4763         sp->lastchar < 256 &&
 4764         sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) {
 4765         IChar repeated[2];
 4766         count = one_if_default(0);
 4767         repeated[0] = (IChar) sp->lastchar;
 4768         while (count-- > 0) {
 4769             dotext(xw,
 4770                screen->gsets[(int) (screen->curgl)],
 4771                repeated, 1);
 4772         }
 4773         }
 4774         ResetState(sp);
 4775         break;
 4776 
 4777     case CASE_LS2:
 4778         TRACE(("CASE_LS2\n"));
 4779         screen->curgl = 2;
 4780         ResetState(sp);
 4781         break;
 4782 
 4783     case CASE_LS3:
 4784         TRACE(("CASE_LS3\n"));
 4785         screen->curgl = 3;
 4786         ResetState(sp);
 4787         break;
 4788 
 4789     case CASE_LS3R:
 4790         TRACE(("CASE_LS3R\n"));
 4791         screen->curgr = 3;
 4792         ResetState(sp);
 4793         break;
 4794 
 4795     case CASE_LS2R:
 4796         TRACE(("CASE_LS2R\n"));
 4797         screen->curgr = 2;
 4798         ResetState(sp);
 4799         break;
 4800 
 4801     case CASE_LS1R:
 4802         TRACE(("CASE_LS1R\n"));
 4803         screen->curgr = 1;
 4804         ResetState(sp);
 4805         break;
 4806 
 4807     case CASE_XTERM_SAVE:
 4808         savemodes(xw);
 4809         ResetState(sp);
 4810         break;
 4811 
 4812     case CASE_XTERM_RESTORE:
 4813         restoremodes(xw);
 4814         ResetState(sp);
 4815         break;
 4816 
 4817     case CASE_XTERM_WINOPS:
 4818         TRACE(("CASE_XTERM_WINOPS\n"));
 4819         window_ops(xw);
 4820         ResetState(sp);
 4821         break;
 4822 #if OPT_WIDE_CHARS
 4823     case CASE_ESC_PERCENT:
 4824         TRACE(("CASE_ESC_PERCENT\n"));
 4825         sp->parsestate = esc_pct_table;
 4826         break;
 4827 
 4828     case CASE_UTF8:
 4829         /* If we did not set UTF-8 mode from resource or the
 4830          * command-line, allow it to be enabled/disabled by
 4831          * control sequence.
 4832          */
 4833         TRACE(("CASE_UTF8 wide:%d, utf8:%d, req:%s\n",
 4834            screen->wide_chars,
 4835            screen->utf8_mode,
 4836            BtoS(c == 'G')));
 4837         if ((!screen->wide_chars) && (c == 'G')) {
 4838         WriteNow();
 4839         ChangeToWide(xw);
 4840         }
 4841         if (screen->wide_chars
 4842         && !screen->utf8_always) {
 4843         switchPtyData(screen, c == 'G');
 4844         TRACE(("UTF8 mode %s\n",
 4845                BtoS(screen->utf8_mode)));
 4846         } else {
 4847         TRACE(("UTF8 mode NOT turned %s (%s)\n",
 4848                BtoS(c == 'G'),
 4849                (screen->utf8_mode == uAlways)
 4850                ? "UTF-8 mode set from command-line"
 4851                : "wideChars resource was not set"));
 4852         }
 4853         ResetState(sp);
 4854         break;
 4855 
 4856     case CASE_SCS_DQUOTE:
 4857         TRACE(("CASE_SCS_DQUOTE\n"));
 4858         sp->parsestate = scs_2qt_table;
 4859         break;
 4860 
 4861     case CASE_GSETS_DQUOTE:
 4862         if (screen->vtXX_level >= 5) {
 4863         TRACE(("CASE_GSETS_DQUOTE(%d) = '%c'\n", sp->scstype, c));
 4864         xtermDecodeSCS(xw, sp->scstype, '"', (int) c);
 4865         }
 4866         ResetState(sp);
 4867         break;
 4868 
 4869     case CASE_SCS_AMPRSND:
 4870         TRACE(("CASE_SCS_AMPRSND\n"));
 4871         sp->parsestate = scs_amp_table;
 4872         break;
 4873 
 4874     case CASE_GSETS_AMPRSND:
 4875         if (screen->vtXX_level >= 5) {
 4876         TRACE(("CASE_GSETS_AMPRSND(%d) = '%c'\n", sp->scstype, c));
 4877         xtermDecodeSCS(xw, sp->scstype, '&', (int) c);
 4878         }
 4879         ResetState(sp);
 4880         break;
 4881 
 4882     case CASE_SCS_PERCENT:
 4883         TRACE(("CASE_SCS_PERCENT\n"));
 4884         sp->parsestate = scs_pct_table;
 4885         break;
 4886 
 4887     case CASE_GSETS_PERCENT:
 4888         if (screen->vtXX_level >= 3) {
 4889         TRACE(("CASE_GSETS_PERCENT(%d) = '%c'\n", sp->scstype, c));
 4890         xtermDecodeSCS(xw, sp->scstype, '%', (int) c);
 4891         }
 4892         ResetState(sp);
 4893         break;
 4894 #endif
 4895 #if OPT_MOD_FKEYS
 4896     case CASE_SET_MOD_FKEYS:
 4897         TRACE(("CASE_SET_MOD_FKEYS\n"));
 4898         if (nparam >= 1) {
 4899         set_mod_fkeys(xw,
 4900                   GetParam(0),
 4901                   ((nparam > 1)
 4902                    ? GetParam(1)
 4903                    : DEFAULT),
 4904                   True);
 4905         } else {
 4906         for (value = 1; value <= 5; ++value)
 4907             set_mod_fkeys(xw, value, DEFAULT, True);
 4908         }
 4909         ResetState(sp);
 4910         break;
 4911 
 4912     case CASE_SET_MOD_FKEYS0:
 4913         TRACE(("CASE_SET_MOD_FKEYS0\n"));
 4914         if (nparam >= 1 && GetParam(0) != DEFAULT) {
 4915         set_mod_fkeys(xw, GetParam(0), -1, False);
 4916         } else {
 4917         xw->keyboard.modify_now.function_keys = -1;
 4918         }
 4919         ResetState(sp);
 4920         break;
 4921 #endif
 4922     case CASE_HIDE_POINTER:
 4923         TRACE(("CASE_HIDE_POINTER\n"));
 4924         if (nparam >= 1 && GetParam(0) != DEFAULT) {
 4925         screen->pointer_mode = GetParam(0);
 4926         } else {
 4927         screen->pointer_mode = DEF_POINTER_MODE;
 4928         }
 4929         ResetState(sp);
 4930         break;
 4931 
 4932     case CASE_SM_TITLE:
 4933         TRACE(("CASE_SM_TITLE\n"));
 4934         if (nparam >= 1) {
 4935         int n;
 4936         for (n = 0; n < nparam; ++n) {
 4937             if (GetParam(n) != DEFAULT)
 4938             screen->title_modes |= (1 << GetParam(n));
 4939         }
 4940         } else {
 4941         screen->title_modes = DEF_TITLE_MODES;
 4942         }
 4943         TRACE(("...title_modes %#x\n", screen->title_modes));
 4944         ResetState(sp);
 4945         break;
 4946 
 4947     case CASE_RM_TITLE:
 4948         TRACE(("CASE_RM_TITLE\n"));
 4949         if (nparam >= 1) {
 4950         int n;
 4951         for (n = 0; n < nparam; ++n) {
 4952             if (GetParam(n) != DEFAULT)
 4953             screen->title_modes &= ~(1 << GetParam(n));
 4954         }
 4955         } else {
 4956         screen->title_modes = DEF_TITLE_MODES;
 4957         }
 4958         TRACE(("...title_modes %#x\n", screen->title_modes));
 4959         ResetState(sp);
 4960         break;
 4961 
 4962     case CASE_CSI_IGNORE:
 4963         sp->parsestate = cigtable;
 4964         break;
 4965 
 4966     case CASE_DECSWBV:
 4967         TRACE(("CASE_DECSWBV\n"));
 4968         switch (zero_if_default(0)) {
 4969         case 2:
 4970         /* FALLTHRU */
 4971         case 3:
 4972         /* FALLTHRU */
 4973         case 4:
 4974         screen->warningVolume = bvLow;
 4975         break;
 4976         case 5:
 4977         /* FALLTHRU */
 4978         case 6:
 4979         /* FALLTHRU */
 4980         case 7:
 4981         /* FALLTHRU */
 4982         case 8:
 4983         screen->warningVolume = bvHigh;
 4984         break;
 4985         default:
 4986         screen->warningVolume = bvOff;
 4987         break;
 4988         }
 4989         TRACE(("...warningVolume %d\n", screen->warningVolume));
 4990         ResetState(sp);
 4991         break;
 4992 
 4993     case CASE_DECSMBV:
 4994         TRACE(("CASE_DECSMBV\n"));
 4995         switch (zero_if_default(0)) {
 4996         case 2:
 4997         /* FALLTHRU */
 4998         case 3:
 4999         /* FALLTHRU */
 5000         case 4:
 5001         screen->marginVolume = bvLow;
 5002         break;
 5003         case 0:
 5004         /* FALLTHRU */
 5005         case 5:
 5006         /* FALLTHRU */
 5007         case 6:
 5008         /* FALLTHRU */
 5009         case 7:
 5010         /* FALLTHRU */
 5011         case 8:
 5012         screen->marginVolume = bvHigh;
 5013         break;
 5014         default:
 5015         screen->marginVolume = bvOff;
 5016         break;
 5017         }
 5018         TRACE(("...marginVolume %d\n", screen->marginVolume));
 5019         ResetState(sp);
 5020         break;
 5021     }
 5022     if (sp->parsestate == sp->groundtable)
 5023         sp->lastchar = thischar;
 5024     } while (0);
 5025 
 5026 #if OPT_WIDE_CHARS
 5027     screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse)
 5028                       && (sp->parsestate != sos_table));
 5029 #endif
 5030 
 5031     return True;
 5032 }
 5033 
 5034 static Boolean
 5035 redoparsing(XtermWidget xw, unsigned c, struct ParseState *sp, unsigned check)
 5036 {
 5037     Boolean result = False;
 5038     if (!(sp->check_recur & check)) {
 5039     UIntSet(sp->check_recur, check);
 5040     result = doparsing(xw, c, sp);
 5041     UIntClr(sp->check_recur, check);
 5042     }
 5043     return result;
 5044 }
 5045 
 5046 static void
 5047 VTparse(XtermWidget xw)
 5048 {
 5049     Boolean keep_running;
 5050 
 5051     /* We longjmp back to this point in VTReset() */
 5052     (void) setjmp(vtjmpbuf);
 5053     init_parser(xw, &myState);
 5054 
 5055     do {
 5056     keep_running = doparsing(xw, doinput(xw), &myState);
 5057     while (myState.defer_used) {
 5058         Char *deferred = myState.defer_area;
 5059         size_t len = myState.defer_used;
 5060         size_t i;
 5061         myState.defer_area = NULL;
 5062         myState.defer_size = 0;
 5063         myState.defer_used = 0;
 5064         for (i = 0; i < len; i++) {
 5065         (void) doparsing(xw, deferred[i], &myState);
 5066         }
 5067         free(deferred);
 5068     }
 5069     } while (keep_running);
 5070 }
 5071 
 5072 static Char *v_buffer;      /* pointer to physical buffer */
 5073 static Char *v_bufstr = NULL;   /* beginning of area to write */
 5074 static Char *v_bufptr;      /* end of area to write */
 5075 static Char *v_bufend;      /* end of physical buffer */
 5076 
 5077 /* Write data to the pty as typed by the user, pasted with the mouse,
 5078    or generated by us in response to a query ESC sequence. */
 5079 
 5080 void
 5081 v_write(int f, const Char *data, unsigned len)
 5082 {
 5083     TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len)));
 5084     if (v_bufstr == NULL) {
 5085     if (len > 0) {
 5086         v_buffer = (Char *) XtMalloc((Cardinal) len);
 5087         v_bufstr = v_buffer;
 5088         v_bufptr = v_buffer;
 5089         v_bufend = v_buffer + len;
 5090     }
 5091     if (v_bufstr == NULL) {
 5092         return;
 5093     }
 5094     }
 5095     if_DEBUG({
 5096     fprintf(stderr, "v_write called with %u bytes (%ld left over)",
 5097         len, (long) (v_bufptr - v_bufstr));
 5098     if (len > 1 && len < 10)
 5099         fprintf(stderr, " \"%.*s\"", len, (const char *) data);
 5100     fprintf(stderr, "\n");
 5101     });
 5102 
 5103 #ifdef VMS
 5104     if ((1 << f) != pty_mask) {
 5105     tt_write((const char *) data, len);
 5106     return;
 5107     }
 5108 #else /* VMS */
 5109     if (!FD_ISSET(f, &pty_mask)) {
 5110     IGNORE_RC(write(f, (const char *) data, (size_t) len));
 5111     return;
 5112     }
 5113 #endif /* VMS */
 5114 
 5115     /*
 5116      * Append to the block we already have.
 5117      * Always doing this simplifies the code, and
 5118      * isn't too bad, either.  If this is a short
 5119      * block, it isn't too expensive, and if this is
 5120      * a long block, we won't be able to write it all
 5121      * anyway.
 5122      */
 5123 
 5124     if (len > 0) {
 5125 #if OPT_DABBREV
 5126     TScreenOf(term)->dabbrev_working = False;   /* break dabbrev sequence */
 5127 #endif
 5128     if (v_bufend < v_bufptr + len) {    /* we've run out of room */
 5129         if (v_bufstr != v_buffer) {
 5130         /* there is unused space, move everything down */
 5131         /* possibly overlapping memmove here */
 5132         if_DEBUG({
 5133             fprintf(stderr, "moving data down %ld\n",
 5134                 (long) (v_bufstr - v_buffer));
 5135         });
 5136         memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr));
 5137         v_bufptr -= v_bufstr - v_buffer;
 5138         v_bufstr = v_buffer;
 5139         }
 5140         if (v_bufend < v_bufptr + len) {
 5141         /* still won't fit: get more space */
 5142         /* Don't use XtRealloc because an error is not fatal. */
 5143         unsigned size = (unsigned) (v_bufptr - v_buffer);
 5144         v_buffer = TypeRealloc(Char, size + len, v_buffer);