"Fossies" - the Fresh Open Source Software Archive

Member "xterm-368/charproc.c" (7 Jun 2021, 363149 Bytes) of package /linux/misc/xterm-368.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: 367_vs_368.

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