summaryrefslogtreecommitdiff
path: root/charproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'charproc.c')
-rw-r--r--charproc.c9843
1 files changed, 9843 insertions, 0 deletions
diff --git a/charproc.c b/charproc.c
new file mode 100644
index 0000000..43899d0
--- /dev/null
+++ b/charproc.c
@@ -0,0 +1,9843 @@
+/* $XTermId: charproc.c,v 1.1220 2012/06/11 08:57:49 tom Exp $ */
+
+/*
+ * Copyright 1999-2011,2012 by Thomas E. Dickey
+ *
+ * All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the
+ * sale, use or other dealings in this Software without prior written
+ * authorization.
+ *
+ *
+ * Copyright 1988 The Open Group
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation.
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of The Open Group shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from The Open Group.
+ *
+ */
+/*
+ * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+ *
+ * All Rights Reserved
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Digital Equipment
+ * Corporation not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ *
+ *
+ * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+ * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/* charproc.c */
+
+#include <version.h>
+#include <xterm.h>
+
+#include <X11/Xatom.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/CharSet.h>
+#include <X11/Xmu/Converters.h>
+
+#if OPT_INPUT_METHOD
+
+#if defined(HAVE_LIB_XAW)
+#include <X11/Xaw/XawImP.h>
+#elif defined(HAVE_LIB_XAW3D)
+#include <X11/Xaw3d/XawImP.h>
+#elif defined(HAVE_LIB_NEXTAW)
+#include <X11/neXtaw/XawImP.h>
+#elif defined(HAVE_LIB_XAWPLUS)
+#include <X11/XawPlus/XawImP.h>
+#endif
+
+#endif
+
+#if OPT_WIDE_CHARS
+#include <wcwidth.h>
+#include <precompose.h>
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+#endif
+
+#if OPT_INPUT_METHOD
+#include <X11/Xlocale.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+
+#if defined(HAVE_SCHED_YIELD)
+#include <sched.h>
+#endif
+
+#include <VTparse.h>
+#include <data.h>
+#include <error.h>
+#include <menu.h>
+#include <main.h>
+#include <fontutils.h>
+#include <xcharmouse.h>
+#include <charclass.h>
+#include <xstrings.h>
+
+typedef void (*BitFunc) (unsigned * /* p */ ,
+ unsigned /* mask */ );
+
+static IChar doinput(void);
+static int set_character_class(char * /*s */ );
+static void FromAlternate(XtermWidget /* xw */ );
+static void ReallyReset(XtermWidget /* xw */ ,
+ Bool /* full */ ,
+ Bool /* saved */ );
+static void RequestResize(XtermWidget /* xw */ ,
+ int /* rows */ ,
+ int /* cols */ ,
+ Bool /* text */ );
+static void SwitchBufs(XtermWidget /* xw */ ,
+ int /* toBuf */ );
+static void ToAlternate(XtermWidget /* xw */ );
+static void ansi_modes(XtermWidget termw,
+ BitFunc /* func */ );
+static void bitclr(unsigned *p, unsigned mask);
+static void bitcpy(unsigned *p, unsigned q, unsigned mask);
+static void bitset(unsigned *p, unsigned mask);
+static void dpmodes(XtermWidget /* xw */ ,
+ BitFunc /* func */ );
+static void restoremodes(XtermWidget /* xw */ );
+static void savemodes(XtermWidget /* xw */ );
+static void window_ops(XtermWidget /* xw */ );
+
+#define DoStartBlinking(s) ((s)->cursor_blink ^ (s)->cursor_blink_esc)
+
+#if OPT_BLINK_CURS || OPT_BLINK_TEXT
+#define UpdateCursorBlink(screen) SetCursorBlink(screen, screen->cursor_blink)
+static void SetCursorBlink(TScreen * /* screen */ ,
+ Bool /* enable */ );
+static void HandleBlinking(XtPointer /* closure */ ,
+ XtIntervalId * /* id */ );
+static void StartBlinking(TScreen * /* screen */ );
+static void StopBlinking(TScreen * /* screen */ );
+#else
+#define StartBlinking(screen) /* nothing */
+#define StopBlinking(screen) /* nothing */
+#endif
+
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+static void PreeditPosition(XtermWidget /* xw */ );
+#endif
+
+#define DEFAULT -1
+#define BELLSUPPRESSMSEC 200
+
+static int nparam;
+static ANSI reply;
+static int param[NPARAM];
+
+static jmp_buf vtjmpbuf;
+
+/* event handlers */
+static void HandleBell PROTO_XT_ACTIONS_ARGS;
+static void HandleIgnore PROTO_XT_ACTIONS_ARGS;
+static void HandleKeymapChange PROTO_XT_ACTIONS_ARGS;
+static void HandleVisualBell PROTO_XT_ACTIONS_ARGS;
+#if HANDLE_STRUCT_NOTIFY
+static void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS;
+#endif
+
+/*
+ * NOTE: VTInitialize zeros out the entire ".screen" component of the
+ * XtermWidget, so make sure to add an assignment statement in VTInitialize()
+ * for each new ".screen" field added to this resource list.
+ */
+
+/* Defaults */
+#if OPT_ISO_COLORS
+
+/*
+ * If we default to colorMode enabled, compile-in defaults for the ANSI colors.
+ */
+#if DFT_COLORMODE
+#define DFT_COLOR(name) name
+#else
+#define DFT_COLOR(name) XtDefaultForeground
+#endif
+#endif
+
+static String _Font_Selected_ = "yes"; /* string is arbitrary */
+
+static const char *defaultTranslations;
+/* *INDENT-OFF* */
+static XtActionsRec actionsList[] = {
+ { "allow-send-events", HandleAllowSends },
+ { "bell", HandleBell },
+ { "clear-saved-lines", HandleClearSavedLines },
+ { "copy-selection", HandleCopySelection },
+ { "create-menu", HandleCreateMenu },
+ { "delete-is-del", HandleDeleteIsDEL },
+ { "dired-button", DiredButton },
+ { "hard-reset", HandleHardReset },
+ { "ignore", HandleIgnore },
+ { "insert", HandleKeyPressed }, /* alias for insert-seven-bit */
+ { "insert-eight-bit", HandleEightBitKeyPressed },
+ { "insert-selection", HandleInsertSelection },
+ { "insert-seven-bit", HandleKeyPressed },
+ { "interpret", HandleInterpret },
+ { "keymap", HandleKeymapChange },
+ { "popup-menu", HandlePopupMenu },
+ { "print", HandlePrintScreen },
+ { "print-everything", HandlePrintEverything },
+ { "print-redir", HandlePrintControlMode },
+ { "quit", HandleQuit },
+ { "redraw", HandleRedraw },
+ { "scroll-back", HandleScrollBack },
+ { "scroll-forw", HandleScrollForward },
+ { "secure", HandleSecure },
+ { "select-cursor-end", HandleKeyboardSelectEnd },
+ { "select-cursor-extend", HandleKeyboardSelectExtend },
+ { "select-cursor-start", HandleKeyboardSelectStart },
+ { "select-end", HandleSelectEnd },
+ { "select-extend", HandleSelectExtend },
+ { "select-set", HandleSelectSet },
+ { "select-start", HandleSelectStart },
+ { "send-signal", HandleSendSignal },
+ { "set-8-bit-control", Handle8BitControl },
+ { "set-allow132", HandleAllow132 },
+ { "set-altscreen", HandleAltScreen },
+ { "set-appcursor", HandleAppCursor },
+ { "set-appkeypad", HandleAppKeypad },
+ { "set-autolinefeed", HandleAutoLineFeed },
+ { "set-autowrap", HandleAutoWrap },
+ { "set-backarrow", HandleBackarrow },
+ { "set-bellIsUrgent", HandleBellIsUrgent },
+ { "set-cursesemul", HandleCursesEmul },
+ { "set-jumpscroll", HandleJumpscroll },
+ { "set-keep-selection", HandleKeepSelection },
+ { "set-marginbell", HandleMarginBell },
+ { "set-old-function-keys", HandleOldFunctionKeys },
+ { "set-pop-on-bell", HandleSetPopOnBell },
+ { "set-reverse-video", HandleReverseVideo },
+ { "set-reversewrap", HandleReverseWrap },
+ { "set-scroll-on-key", HandleScrollKey },
+ { "set-scroll-on-tty-output", HandleScrollTtyOutput },
+ { "set-scrollbar", HandleScrollbar },
+ { "set-select", HandleSetSelect },
+ { "set-sun-keyboard", HandleSunKeyboard },
+ { "set-titeInhibit", HandleTiteInhibit },
+ { "set-visual-bell", HandleSetVisualBell },
+ { "set-vt-font", HandleSetFont },
+ { "soft-reset", HandleSoftReset },
+ { "start-cursor-extend", HandleKeyboardStartExtend },
+ { "start-extend", HandleStartExtend },
+ { "string", HandleStringEvent },
+ { "vi-button", ViButton },
+ { "visual-bell", HandleVisualBell },
+#ifdef ALLOWLOGGING
+ { "set-logging", HandleLogging },
+#endif
+#if OPT_ALLOW_XXX_OPS
+ { "allow-color-ops", HandleAllowColorOps },
+ { "allow-font-ops", HandleAllowFontOps },
+ { "allow-tcap-ops", HandleAllowTcapOps },
+ { "allow-title-ops", HandleAllowTitleOps },
+ { "allow-window-ops", HandleAllowWindowOps },
+#endif
+#if OPT_BLINK_CURS
+ { "set-cursorblink", HandleCursorBlink },
+#endif
+#if OPT_BOX_CHARS
+ { "set-font-linedrawing", HandleFontBoxChars },
+ { "set-font-packed", HandleFontPacked },
+#endif
+#if OPT_DABBREV
+ { "dabbrev-expand", HandleDabbrevExpand },
+#endif
+#if OPT_DEC_CHRSET
+ { "set-font-doublesize", HandleFontDoublesize },
+#endif
+#if OPT_DEC_SOFTFONT
+ { "set-font-loading", HandleFontLoading },
+#endif
+#if OPT_EXEC_XTERM
+ { "spawn-new-terminal", HandleSpawnTerminal },
+#endif
+#if OPT_HP_FUNC_KEYS
+ { "set-hp-function-keys", HandleHpFunctionKeys },
+#endif
+#if OPT_LOAD_VTFONTS
+ { "load-vt-fonts", HandleLoadVTFonts },
+#endif
+#if OPT_MAXIMIZE
+ { "deiconify", HandleDeIconify },
+ { "fullscreen", HandleFullscreen },
+ { "iconify", HandleIconify },
+ { "maximize", HandleMaximize },
+ { "restore", HandleRestoreSize },
+#endif
+#if OPT_NUM_LOCK
+ { "alt-sends-escape", HandleAltEsc },
+ { "meta-sends-escape", HandleMetaEsc },
+ { "set-num-lock", HandleNumLock },
+#endif
+#if OPT_READLINE
+ { "readline-button", ReadLineButton },
+#endif
+#if OPT_RENDERFONT
+ { "set-render-font", HandleRenderFont },
+#endif
+#if OPT_SCO_FUNC_KEYS
+ { "set-sco-function-keys", HandleScoFunctionKeys },
+#endif
+#if OPT_SCROLL_LOCK
+ { "scroll-lock", HandleScrollLock },
+#endif
+#if OPT_SELECTION_OPS
+ { "exec-formatted", HandleExecFormatted },
+ { "exec-selectable", HandleExecSelectable },
+ { "insert-formatted", HandleInsertFormatted },
+ { "insert-selectable", HandleInsertSelectable },
+#endif
+#if OPT_SHIFT_FONTS
+ { "larger-vt-font", HandleLargerFont },
+ { "smaller-vt-font", HandleSmallerFont },
+#endif
+#if OPT_SUN_FUNC_KEYS
+ { "set-sun-function-keys", HandleSunFunctionKeys },
+#endif
+#if OPT_TEK4014
+ { "set-terminal-type", HandleSetTerminalType },
+ { "set-visibility", HandleVisibility },
+ { "set-tek-text", HandleSetTekText },
+ { "tek-page", HandleTekPage },
+ { "tek-reset", HandleTekReset },
+ { "tek-copy", HandleTekCopy },
+#endif
+#if OPT_TOOLBAR
+ { "set-toolbar", HandleToolbar },
+#endif
+#if OPT_WIDE_CHARS
+ { "set-utf8-mode", HandleUTF8Mode },
+ { "set-utf8-fonts", HandleUTF8Fonts },
+ { "set-utf8-title", HandleUTF8Title },
+#endif
+};
+/* *INDENT-ON* */
+
+#define SPS screen.printer_state
+
+static XtResource xterm_resources[] =
+{
+ Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False),
+ Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR),
+ Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT),
+ Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP),
+ Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE),
+ Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW),
+ Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False),
+ Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC),
+ Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True),
+ Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False),
+ Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False),
+ Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False),
+ Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False),
+ Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True),
+ Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False),
+ Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False),
+ Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_DEL),
+ Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False),
+ Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True),
+ Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True),
+ Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False),
+ Bres(XtNc132, XtCC132, screen.c132, False),
+ Bres(XtNcurses, XtCCurses, screen.curses, False),
+ Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True),
+ Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine,
+ screen.cutToBeginningOfLine, True),
+ Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL),
+ Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True),
+ Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False),
+ Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True),
+ Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True),
+ Bres(XtNhighlightSelection, XtCHighlightSelection,
+ screen.highlight_selection, False),
+ Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False),
+ Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False),
+ Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True),
+ Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False),
+ Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True),
+ Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True),
+ Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False),
+ Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False),
+ Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC),
+ Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False),
+ Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False),
+ Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False),
+ Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False),
+ Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False),
+ Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False),
+ Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True),
+ Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False),
+ Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False),
+ Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False),
+ Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False),
+ Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False),
+ Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True),
+ Bres(XtNselectToClipboard, XtCSelectToClipboard,
+ screen.selectToClipboard, False),
+ Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False),
+ Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False),
+ Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False),
+ Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False),
+ Bres(XtNunderLine, XtCUnderLine, screen.underline, True),
+ Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False),
+ Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False),
+
+ Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"),
+
+ Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC),
+ Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource),
+ Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER),
+ Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1),
+ Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME),
+ Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL),
+ Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE),
+ Ires(XtNprinterControlMode, XtCPrinterControlMode,
+ SPS.printer_controlmode, 0),
+ Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES),
+ Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100),
+ Ires(XtNsaveLines, XtCSaveLines, screen.savelines, SAVELINES),
+ Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1),
+ Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, SCROLLLINES),
+
+ Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL),
+ Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL),
+ Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL),
+ Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL),
+ Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL),
+ Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL),
+ Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL),
+
+ Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""),
+ Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT),
+ Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL),
+ Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID),
+ Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"),
+ Sres(XtNdisallowedColorOps, XtCDisallowedColorOps,
+ screen.disallowedColorOps, DEF_DISALLOWED_COLOR),
+ Sres(XtNdisallowedFontOps, XtCDisallowedFontOps,
+ screen.disallowedFontOps, DEF_DISALLOWED_FONT),
+ Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps,
+ screen.disallowedTcapOps, DEF_DISALLOWED_TCAP),
+ Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps,
+ screen.disallowedWinOps, DEF_DISALLOWED_WINDOW),
+ Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META),
+ Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes,
+ screen.eightbit_select_types, NULL),
+ Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT),
+ Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL),
+ Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT),
+ Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""),
+ Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL),
+
+ Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground),
+ Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground),
+ Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground),
+ Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground),
+ Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground),
+
+ {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity),
+ XtOffsetOf(XtermWidgetRec, misc.resizeGravity),
+ XtRImmediate, (XtPointer) SouthWestGravity},
+
+ {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor),
+ XtOffsetOf(XtermWidgetRec, screen.pointer_cursor),
+ XtRString, (XtPointer) "xterm"},
+
+#ifdef ALLOWLOGGING
+ Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False),
+ Bres(XtNlogging, XtCLogging, misc.log_on, False),
+ Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL),
+#endif
+
+#ifndef NO_ACTIVE_ICON
+ Bres("activeIcon", "ActiveIcon", misc.active_icon, False),
+ Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2),
+ Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"),
+ Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground),
+#endif /* NO_ACTIVE_ICON */
+
+#if OPT_BLINK_CURS
+ Bres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink, False),
+#endif
+ Bres(XtNcursorUnderline, XtCCursorUnderline, screen.cursor_underline, False),
+
+#if OPT_BLINK_TEXT
+ Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD),
+#endif
+
+#if OPT_BLINK_CURS || OPT_BLINK_TEXT
+ Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600),
+ Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300),
+#endif
+
+#if OPT_BOX_CHARS
+ Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False),
+ Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True),
+ Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False),
+#endif
+
+#if OPT_BROKEN_OSC
+ Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True),
+#endif
+
+#if OPT_BROKEN_ST
+ Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False),
+#endif
+
+#if OPT_C1_PRINT
+ Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False),
+#endif
+
+#if OPT_CLIP_BOLD
+ Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True),
+#endif
+
+#if OPT_DEC_CHRSET
+ Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True),
+ Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET),
+#endif
+
+#if OPT_HIGHLIGHT_COLOR
+ Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground),
+ Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground),
+ Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True),
+ Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe),
+#endif /* OPT_HIGHLIGHT_COLOR */
+
+#if OPT_INPUT_METHOD
+ Bres(XtNopenIm, XtCOpenIm, misc.open_im, True),
+ Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL),
+ Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type,
+ "OverTheSpot,Root"),
+ Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3),
+#endif
+
+#if OPT_ISO_COLORS
+ Bres(XtNboldColors, XtCColorMode, screen.boldColors, True),
+ Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0),
+ Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE),
+
+ Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False),
+ Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False),
+ Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False),
+ Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False),
+ Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False),
+ Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False),
+
+ COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")),
+ COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")),
+ COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")),
+ COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")),
+ COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)),
+ COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")),
+ COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")),
+ COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")),
+ COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")),
+ COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")),
+ COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")),
+ COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")),
+ COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)),
+ COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")),
+ COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")),
+ COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")),
+ COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)),
+ COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)),
+ COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)),
+ COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)),
+
+#if !OPT_COLOR_RES2
+#if OPT_256_COLORS
+# include <256colres.h>
+#elif OPT_88_COLORS
+# include <88colres.h>
+#endif
+#endif /* !OPT_COLOR_RES2 */
+
+#endif /* OPT_ISO_COLORS */
+
+ CLICK_RES("2", screen.onClick[1], "word"),
+ CLICK_RES("3", screen.onClick[2], "line"),
+ CLICK_RES("4", screen.onClick[3], 0),
+ CLICK_RES("5", screen.onClick[4], 0),
+
+#if OPT_MOD_FKEYS
+ Ires(XtNmodifyKeyboard, XtCModifyKeyboard,
+ keyboard.modify_1st.allow_keys, 0),
+ Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys,
+ keyboard.modify_1st.cursor_keys, 2),
+ Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys,
+ keyboard.modify_1st.function_keys, 2),
+ Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys,
+ keyboard.modify_1st.keypad_keys, 0),
+ Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys,
+ keyboard.modify_1st.other_keys, 0),
+ Ires(XtNmodifyStringKeys, XtCModifyStringKeys,
+ keyboard.modify_1st.string_keys, 0),
+ Ires(XtNformatOtherKeys, XtCFormatOtherKeys,
+ keyboard.format_keys, 0),
+#endif
+
+#if OPT_NUM_LOCK
+ Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False),
+ Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True),
+#endif
+
+#if OPT_PRINT_COLORS
+ Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1),
+#endif
+
+#if OPT_SHIFT_FONTS
+ Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True),
+#endif
+
+#if OPT_SUNPC_KBD
+ Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10),
+#endif
+
+#if OPT_TEK4014
+ Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False),
+ Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False),
+ Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False),
+#endif
+
+#if OPT_TOOLBAR
+ Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0),
+ Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25),
+#endif
+
+#if OPT_WIDE_CHARS
+ Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False),
+ Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False),
+ Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True),
+ Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False),
+ Bres(XtNutf8Title, XtCUtf8Title, screen.utf8_title, False),
+ Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True),
+ Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False),
+ Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2),
+ Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 256),
+ Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 1024),
+ Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"),
+ Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"),
+ Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT),
+ Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT),
+ Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL),
+#endif
+
+#if OPT_LUIT_PROG
+ Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"),
+ Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER),
+#endif
+
+#if OPT_INPUT_METHOD
+ Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT),
+#endif
+
+#if OPT_SCROLL_LOCK
+ Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False),
+#endif
+
+#if OPT_XMC_GLITCH
+ Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False),
+ Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True),
+ Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1),
+ Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0),
+#endif
+
+#ifdef SCROLLBAR_RIGHT
+ Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False),
+#endif
+
+#if OPT_RENDERFONT
+#define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0")
+ RES_FACESIZE(1),
+ RES_FACESIZE(2),
+ RES_FACESIZE(3),
+ RES_FACESIZE(4),
+ RES_FACESIZE(5),
+ RES_FACESIZE(6),
+ Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE),
+ Sres(XtNfaceName, XtCFaceName, misc.face_name, DEFFACENAME),
+ Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.face_wide_name, DEFFACENAME),
+ Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"),
+#endif
+};
+
+static Boolean VTSetValues(Widget cur, Widget request, Widget new_arg,
+ ArgList args, Cardinal *num_args);
+static void VTClassInit(void);
+static void VTDestroy(Widget w);
+static void VTExpose(Widget w, XEvent * event, Region region);
+static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args,
+ Cardinal *num_args);
+static void VTRealize(Widget w, XtValueMask * valuemask,
+ XSetWindowAttributes * values);
+static void VTResize(Widget w);
+
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+static void VTInitI18N(XtermWidget);
+#endif
+
+#ifdef VMS
+globaldef {
+ "xtermclassrec"
+} noshare
+
+#else
+static
+#endif /* VMS */
+WidgetClassRec xtermClassRec =
+{
+ {
+ /* core_class fields */
+ (WidgetClass) & widgetClassRec, /* superclass */
+ "VT100", /* class_name */
+ sizeof(XtermWidgetRec), /* widget_size */
+ VTClassInit, /* class_initialize */
+ NULL, /* class_part_initialize */
+ False, /* class_inited */
+ VTInitialize, /* initialize */
+ NULL, /* initialize_hook */
+ VTRealize, /* realize */
+ actionsList, /* actions */
+ XtNumber(actionsList), /* num_actions */
+ xterm_resources, /* resources */
+ XtNumber(xterm_resources), /* num_resources */
+ NULLQUARK, /* xrm_class */
+ True, /* compress_motion */
+ False, /* compress_exposure */
+ True, /* compress_enterleave */
+ False, /* visible_interest */
+ VTDestroy, /* destroy */
+ VTResize, /* resize */
+ VTExpose, /* expose */
+ VTSetValues, /* set_values */
+ NULL, /* set_values_hook */
+ XtInheritSetValuesAlmost, /* set_values_almost */
+ NULL, /* get_values_hook */
+ NULL, /* accept_focus */
+ XtVersion, /* version */
+ NULL, /* callback_offsets */
+ 0, /* tm_table */
+ XtInheritQueryGeometry, /* query_geometry */
+ XtInheritDisplayAccelerator, /* display_accelerator */
+ NULL /* extension */
+ }
+};
+
+#ifdef VMS
+globaldef {
+ "xtermwidgetclass"
+}
+noshare
+#endif /* VMS */
+WidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec;
+
+/*
+ * Add input-actions for widgets that are overlooked (scrollbar and toolbar):
+ *
+ * a) Sometimes the scrollbar passes through translations, sometimes it
+ * doesn't. We add the KeyPress translations here, just to be sure.
+ * b) In the normal (non-toolbar) configuration, the xterm widget covers
+ * almost all of the window. With a toolbar, there's a relatively
+ * large area that the user would expect to enter keystrokes since the
+ * program can get the focus.
+ */
+void
+xtermAddInput(Widget w)
+{
+ /* *INDENT-OFF* */
+ XtActionsRec input_actions[] = {
+ { "insert", HandleKeyPressed }, /* alias */
+ { "insert-eight-bit", HandleEightBitKeyPressed },
+ { "insert-seven-bit", HandleKeyPressed },
+ { "secure", HandleSecure },
+ { "string", HandleStringEvent },
+ { "scroll-back", HandleScrollBack },
+ { "scroll-forw", HandleScrollForward },
+ { "select-cursor-end", HandleKeyboardSelectEnd },
+ { "select-cursor-extend", HandleKeyboardSelectExtend },
+ { "select-cursor-start", HandleKeyboardSelectStart },
+ { "insert-selection", HandleInsertSelection },
+ { "select-start", HandleSelectStart },
+ { "select-extend", HandleSelectExtend },
+ { "start-extend", HandleStartExtend },
+ { "select-end", HandleSelectEnd },
+ { "clear-saved-lines", HandleClearSavedLines },
+ { "popup-menu", HandlePopupMenu },
+ { "bell", HandleBell },
+ { "ignore", HandleIgnore },
+#if OPT_DABBREV
+ { "dabbrev-expand", HandleDabbrevExpand },
+#endif
+#if OPT_MAXIMIZE
+ { "fullscreen", HandleFullscreen },
+#endif
+#if OPT_SCROLL_LOCK
+ { "scroll-lock", HandleScrollLock },
+#endif
+#if OPT_SHIFT_FONTS
+ { "larger-vt-font", HandleLargerFont },
+ { "smaller-vt-font", HandleSmallerFont },
+#endif
+ };
+ /* *INDENT-ON* */
+
+ TRACE_TRANS("BEFORE", w);
+ XtAppAddActions(app_con, input_actions, XtNumber(input_actions));
+ XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations));
+ TRACE_TRANS("AFTER:", w);
+
+#if OPT_EXTRA_PASTE
+ if (term && term->keyboard.extra_translations)
+ XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations));
+#endif
+}
+
+#if OPT_ISO_COLORS
+#ifdef EXP_BOGUS_FG
+static Bool
+CheckBogusForeground(TScreen * screen, const char *tag)
+{
+ int row = -1, col = -1, pass;
+ Bool isClear = True;
+
+ (void) tag;
+ for (pass = 0; pass < 2; ++pass) {
+ row = screen->cur_row;
+ for (; isClear && (row <= screen->max_row); ++row) {
+ LineData *ld = getLineData(screen, row)->;
+
+ if (ld != 0) {
+ Char *attribs = ld->attribs;
+
+ col = (row == screen->cur_row) ? screen->cur_col : 0;
+ for (; isClear && (col <= screen->max_col); ++col) {
+ unsigned flags = attribs[col];
+ if (pass) {
+ flags &= ~FG_COLOR;
+ attribs[col] = (Char) flags;
+ } else if ((flags & BG_COLOR)) {
+ isClear = False;
+ } else if ((flags & FG_COLOR)) {
+ unsigned ch = ld->charData[col];
+ isClear = ((ch == ' ') || (ch == 0));
+ } else {
+ isClear = False;
+ }
+ }
+ }
+ }
+ }
+ TRACE(("%s checked %d,%d to %d,%d %s pass %d\n",
+ tag, screen->cur_row, screen->cur_col,
+ row, col,
+ isClear && pass ? "cleared" : "unchanged",
+ pass));
+
+ return isClear;
+}
+#endif
+
+/*
+ * The terminal's foreground and background colors are set via two mechanisms:
+ * text (cur_foreground, cur_background values that are passed down to
+ * XDrawImageString and XDrawString)
+ * area (X11 graphics context used in XClearArea and XFillRectangle)
+ */
+void
+SGR_Foreground(XtermWidget xw, int color)
+{
+ TScreen *screen = TScreenOf(xw);
+ Pixel fg;
+
+ if (color >= 0) {
+ UIntSet(xw->flags, FG_COLOR);
+ } else {
+ UIntClr(xw->flags, FG_COLOR);
+ }
+ fg = getXtermForeground(xw, xw->flags, color);
+ xw->cur_foreground = color;
+
+ setCgsFore(xw, WhichVWin(screen), gcNorm, fg);
+ setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg);
+
+ setCgsFore(xw, WhichVWin(screen), gcBold, fg);
+ setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg);
+
+#ifdef EXP_BOGUS_FG
+ /*
+ * If we've just turned off the foreground color, check for blank cells
+ * which have no background color, but do have foreground color. This
+ * could happen due to setting the foreground color just before scrolling.
+ *
+ * Those cells look uncolored, but will confuse ShowCursor(), which looks
+ * for the colors in the current cell, and will see the foreground color.
+ * In that case, remove the foreground color from the blank cells.
+ */
+ if (color < 0) {
+ CheckBogusForeground(screen, "SGR_Foreground");
+ }
+#endif
+}
+
+void
+SGR_Background(XtermWidget xw, int color)
+{
+ TScreen *screen = TScreenOf(xw);
+ Pixel bg;
+
+ /*
+ * An indexing operation may have set screen->scroll_amt, which would
+ * normally result in calling FlushScroll() in WriteText(). However,
+ * if we're changing the background color now, then the new value
+ * should not apply to the pending blank lines.
+ */
+ if (screen->scroll_amt && (color != xw->cur_background))
+ FlushScroll(xw);
+
+ if (color >= 0) {
+ UIntSet(xw->flags, BG_COLOR);
+ } else {
+ UIntClr(xw->flags, BG_COLOR);
+ }
+ bg = getXtermBackground(xw, xw->flags, color);
+ xw->cur_background = color;
+
+ setCgsBack(xw, WhichVWin(screen), gcNorm, bg);
+ setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg);
+
+ setCgsBack(xw, WhichVWin(screen), gcBold, bg);
+ setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg);
+}
+
+/* Invoked after updating bold/underline flags, computes the extended color
+ * index to use for foreground. (See also 'extract_fg()').
+ */
+static void
+setExtendedFG(XtermWidget xw)
+{
+ int fg = xw->sgr_foreground;
+
+ if (TScreenOf(xw)->colorAttrMode
+ || (fg < 0)) {
+ fg = MapToColorMode(fg, TScreenOf(xw), xw->flags);
+ }
+
+ /* This implements the IBM PC-style convention of 8-colors, with one
+ * bit for bold, thus mapping the 0-7 codes to 8-15. It won't make
+ * much sense for 16-color applications, but we keep it to retain
+ * compatiblity with ANSI-color applications.
+ */
+#if OPT_PC_COLORS /* XXXJTL should be settable at runtime (resource or OSC?) */
+ if (TScreenOf(xw)->boldColors
+ && (!xw->sgr_extended)
+ && (fg >= 0)
+ && (fg < 8)
+ && (xw->flags & BOLD))
+ fg |= 8;
+#endif
+
+ SGR_Foreground(xw, fg);
+}
+
+/* Invoked after updating inverse flag, computes the extended color
+ * index to use for background. (See also 'extract_bg()').
+ */
+static void
+setExtendedBG(XtermWidget xw)
+{
+ int bg = xw->sgr_background;
+
+ if (TScreenOf(xw)->colorAttrMode
+ || (bg < 0)) {
+ if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE))
+ bg = COLOR_RV;
+ }
+
+ SGR_Background(xw, bg);
+}
+
+static void
+reset_SGR_Foreground(XtermWidget xw)
+{
+ xw->sgr_foreground = -1;
+ xw->sgr_extended = False;
+ setExtendedFG(xw);
+}
+
+static void
+reset_SGR_Background(XtermWidget xw)
+{
+ xw->sgr_background = -1;
+ setExtendedBG(xw);
+}
+
+static void
+reset_SGR_Colors(XtermWidget xw)
+{
+ reset_SGR_Foreground(xw);
+ reset_SGR_Background(xw);
+}
+#endif /* OPT_ISO_COLORS */
+
+void
+resetCharsets(TScreen * screen)
+{
+ TRACE(("resetCharsets\n"));
+
+ screen->gsets[0] = 'B'; /* ASCII_G */
+ screen->gsets[1] = 'B'; /* ASCII_G */
+ screen->gsets[2] = 'B'; /* ASCII_G */
+ screen->gsets[3] = 'B'; /* ASCII_G */
+
+ screen->curgl = 0; /* G0 => GL. */
+ screen->curgr = 2; /* G2 => GR. */
+ screen->curss = 0; /* No single shift. */
+
+#if OPT_VT52_MODE
+ if (screen->vtXX_level == 0)
+ screen->gsets[1] = '0'; /* Graphics */
+#endif
+}
+
+/*
+ * VT300 and up support three ANSI conformance levels, defined according to
+ * the dpANSI X3.134.1 standard. DEC's manuals equate levels 1 and 2, and
+ * are unclear. This code is written based on the manuals.
+ */
+static void
+set_ansi_conformance(TScreen * screen, int level)
+{
+ TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n",
+ level,
+ screen->vtXX_level * 100,
+ screen->terminal_id,
+ screen->ansi_level));
+ if (screen->vtXX_level >= 3) {
+ switch (screen->ansi_level = level) {
+ case 1:
+ /* FALLTHRU */
+ case 2:
+ screen->gsets[0] = 'B'; /* G0 is ASCII */
+ screen->gsets[1] = 'B'; /* G1 is ISO Latin-1 */
+ screen->curgl = 0;
+ screen->curgr = 1;
+ break;
+ case 3:
+ screen->gsets[0] = 'B'; /* G0 is ASCII */
+ screen->curgl = 0;
+ break;
+ }
+ }
+}
+
+/*
+ * Set scrolling margins. VTxxx terminals require that the top/bottom are
+ * different, so we have at least two lines in the scrolling region.
+ */
+void
+set_tb_margins(TScreen * screen, int top, int bottom)
+{
+ TRACE(("set_tb_margins %d..%d, prior %d..%d\n",
+ top, bottom,
+ screen->top_marg,
+ screen->bot_marg));
+ if (bottom > top) {
+ screen->top_marg = top;
+ screen->bot_marg = bottom;
+ }
+ if (screen->top_marg > screen->max_row)
+ screen->top_marg = screen->max_row;
+ if (screen->bot_marg > screen->max_row)
+ screen->bot_marg = screen->max_row;
+}
+
+void
+set_lr_margins(TScreen * screen, int left, int right)
+{
+ TRACE(("set_lr_margins %d..%d, prior %d..%d\n",
+ left, right,
+ screen->lft_marg,
+ screen->rgt_marg));
+ if (right > left) {
+ screen->lft_marg = left;
+ screen->rgt_marg = right;
+ }
+ if (screen->lft_marg > screen->max_col)
+ screen->lft_marg = screen->max_col;
+ if (screen->rgt_marg > screen->max_col)
+ screen->rgt_marg = screen->max_col;
+}
+
+#define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row)
+#define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col)
+
+static void
+reset_margins(TScreen * screen)
+{
+ reset_tb_margins(screen);
+ reset_lr_margins(screen);
+}
+
+void
+set_max_col(TScreen * screen, int cols)
+{
+ TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col));
+ if (cols < 0)
+ cols = 0;
+ screen->max_col = cols;
+}
+
+void
+set_max_row(TScreen * screen, int rows)
+{
+ TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row));
+ if (rows < 0)
+ rows = 0;
+ screen->max_row = rows;
+}
+
+#if OPT_MOD_FKEYS
+static void
+set_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled)
+{
+#define SET_MOD_FKEYS(field) \
+ xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \
+ ? xw->keyboard.modify_1st.field \
+ : what; \
+ TRACE(("set modify_now.%s to %d\n", #field, \
+ xw->keyboard.modify_now.field));
+
+ switch (which) {
+ case 0:
+ SET_MOD_FKEYS(allow_keys);
+ break;
+ case 1:
+ SET_MOD_FKEYS(cursor_keys);
+ break;
+ case 2:
+ SET_MOD_FKEYS(function_keys);
+ break;
+ case 3:
+ SET_MOD_FKEYS(keypad_keys);
+ break;
+ case 4:
+ SET_MOD_FKEYS(other_keys);
+ break;
+ case 5:
+ SET_MOD_FKEYS(string_keys);
+ break;
+ }
+}
+#endif /* OPT_MOD_FKEYS */
+
+#if OPT_TRACE
+#define WHICH_TABLE(name) if (table == name) result = #name
+static const char *
+which_table(Const PARSE_T * table)
+{
+ const char *result = "?";
+ /* *INDENT-OFF* */
+ WHICH_TABLE (ansi_table);
+ else WHICH_TABLE (cigtable);
+ else WHICH_TABLE (csi2_table);
+ else WHICH_TABLE (csi_ex_table);
+ else WHICH_TABLE (csi_quo_table);
+ else WHICH_TABLE (csi_table);
+ else WHICH_TABLE (dec2_table);
+ else WHICH_TABLE (dec3_table);
+ else WHICH_TABLE (dec_table);
+ else WHICH_TABLE (eigtable);
+ else WHICH_TABLE (esc_sp_table);
+ else WHICH_TABLE (esc_table);
+ else WHICH_TABLE (scrtable);
+ else WHICH_TABLE (scs96table);
+ else WHICH_TABLE (scstable);
+ else WHICH_TABLE (sos_table);
+#if OPT_BLINK_CURS
+ else WHICH_TABLE (csi_sp_table);
+#endif
+#if OPT_DEC_LOCATOR
+ else WHICH_TABLE (csi_tick_table);
+#endif
+#if OPT_DEC_RECTOPS
+ else WHICH_TABLE (csi_dollar_table);
+ else WHICH_TABLE (csi_star_table);
+ else WHICH_TABLE (csi_dec_dollar_table);
+#endif
+#if OPT_WIDE_CHARS
+ else WHICH_TABLE (esc_pct_table);
+#endif
+#if OPT_VT52_MODE
+ else WHICH_TABLE (vt52_table);
+ else WHICH_TABLE (vt52_esc_table);
+ else WHICH_TABLE (vt52_ignore_table);
+#endif
+ /* *INDENT-ON* */
+
+ return result;
+}
+#endif
+
+ /* allocate larger buffer if needed/possible */
+#define SafeAlloc(type, area, used, size) \
+ type *new_string = area; \
+ size_t new_length = size; \
+ if (new_length == 0) { \
+ new_length = 256; \
+ new_string = TypeMallocN(type, new_length); \
+ } else if (used+1 >= new_length) { \
+ new_length = size * 2; \
+ new_string = TypeMallocN(type, new_length); \
+ if (new_string != 0 \
+ && area != 0 \
+ && used != 0) \
+ memcpy(new_string, area, used * sizeof(type)); \
+ }
+
+#define WriteNow() { \
+ unsigned single = 0; \
+ \
+ if (screen->curss) { \
+ dotext(xw, \
+ screen->gsets[(int) (screen->curss)], \
+ sp->print_area, \
+ (Cardinal) 1); \
+ screen->curss = 0; \
+ single++; \
+ } \
+ if (sp->print_used > single) { \
+ dotext(xw, \
+ screen->gsets[(int) (screen->curgl)], \
+ sp->print_area + single, \
+ (Cardinal) (sp->print_used - single)); \
+ } \
+ sp->print_used = 0; \
+ } \
+
+struct ParseState {
+#if OPT_VT52_MODE
+ Bool vt52_cup;
+#endif
+ Const PARSE_T *groundtable;
+ Const PARSE_T *parsestate;
+ int scstype;
+ int scssize;
+ Bool private_function; /* distinguish private-mode from standard */
+ int string_mode; /* nonzero iff we're processing a string */
+ int lastchar; /* positive iff we had a graphic character */
+ int nextstate;
+#if OPT_WIDE_CHARS
+ int last_was_wide;
+#endif
+ /* Buffer for processing printable text */
+ IChar *print_area;
+ size_t print_size;
+ size_t print_used;
+ /* Buffer for processing strings (e.g., OSC ... ST) */
+ Char *string_area;
+ size_t string_size;
+ size_t string_used;
+};
+
+static struct ParseState myState;
+
+static void
+init_groundtable(TScreen * screen, struct ParseState *sp)
+{
+ (void) screen;
+
+#if OPT_VT52_MODE
+ if (!(screen->vtXX_level)) {
+ sp->groundtable = vt52_table;
+ } else if (screen->terminal_id >= 100)
+#endif
+ {
+ sp->groundtable = ansi_table;
+ }
+}
+
+static void
+select_charset(struct ParseState *sp, int type, int size)
+{
+ TRACE(("select_charset %#x %d\n", type, size));
+ sp->scstype = type;
+ sp->scssize = size;
+ if (size == 94) {
+ sp->parsestate = scstable;
+ } else {
+ sp->parsestate = scs96table;
+ }
+}
+
+static int
+zero_if_default(int which)
+{
+ int result = (nparam > which) ? param[which] : 0;
+ if (result <= 0)
+ result = 0;
+ return result;
+}
+
+static int
+one_if_default(int which)
+{
+ int result = (nparam > which) ? param[which] : 0;
+ if (result <= 0)
+ result = 1;
+ return result;
+}
+
+#if OPT_C1_PRINT || OPT_WIDE_CHARS
+#define ParseSOS(screen) ((screen)->c1_printable == 0)
+#else
+#define ParseSOS(screen) 0
+#endif
+
+#define ResetState(sp) (sp)->parsestate = (sp)->groundtable
+
+static void
+illegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp)
+{
+ ResetState(sp);
+ sp->nextstate = sp->parsestate[E2A(c)];
+ Bell(xw, XkbBI_MinorError, 0);
+}
+
+static void
+init_parser(XtermWidget xw, struct ParseState *sp)
+{
+ TScreen *screen = TScreenOf(xw);
+
+ memset(sp, 0, sizeof(*sp));
+ sp->scssize = 94; /* number of printable/nonspace ASCII */
+ sp->lastchar = -1; /* not a legal IChar */
+ sp->nextstate = -1; /* not a legal state */
+
+ init_groundtable(screen, sp);
+ ResetState(sp);
+}
+
+static void
+init_reply(unsigned type)
+{
+ memset(&reply, 0, sizeof(reply));
+ reply.a_type = (Char) type;
+}
+
+static Boolean
+doparsing(XtermWidget xw, unsigned c, struct ParseState *sp)
+{
+ TScreen *screen = TScreenOf(xw);
+ int row;
+ int col;
+ int count;
+ int laststate;
+ int thischar = -1;
+ XTermRect myRect;
+
+ do {
+#if OPT_WIDE_CHARS
+ int this_is_wide = 0;
+
+ /*
+ * Handle zero-width combining characters. Make it faster by noting
+ * that according to the Unicode charts, the majority of Western
+ * character sets do not use this feature. There are some unassigned
+ * codes at 0x242, but no zero-width characters until past 0x300.
+ */
+ if (c >= 0x300
+ && screen->wide_chars
+ && my_wcwidth((int) c) == 0
+ && !isWideControl(c)) {
+ int prev, test;
+ Boolean used = True;
+ int use_row;
+ int use_col;
+
+ WriteNow();
+ use_row = (screen->char_was_written
+ ? screen->last_written_row
+ : screen->cur_row);
+ use_col = (screen->char_was_written
+ ? screen->last_written_col
+ : screen->cur_col);
+
+ /*
+ * Check if the latest data can be added to the base character.
+ * If there is already a combining character stored for the cell,
+ * we cannot, since that would change the order.
+ */
+ if (screen->normalized_c
+ && !IsCellCombined(screen, use_row, use_col)) {
+ prev = (int) XTERM_CELL(use_row, use_col);
+ test = do_precomposition(prev, (int) c);
+ TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n",
+ prev, my_wcwidth(prev),
+ (int) c, my_wcwidth((int) c),
+ test, my_wcwidth(test)));
+ } else {
+ prev = -1;
+ test = -1;
+ }
+
+ /* substitute combined character with precomposed character
+ * only if it does not change the width of the base character
+ */
+ if (test != -1 && my_wcwidth(test) == my_wcwidth(prev)) {
+ putXtermCell(screen, use_row, use_col, test);
+ } else if (screen->char_was_written
+ || getXtermCell(screen, use_row, use_col) > ' ') {
+ addXtermCombining(screen, use_row, use_col, c);
+ } else {
+ /*
+ * none of the above... we will add the combining character as
+ * a base character.
+ */
+ used = False;
+ }
+
+ if (used) {
+ if (!screen->scroll_amt)
+ ScrnUpdate(xw, use_row, use_col, 1, 1, 1);
+ continue;
+ }
+ }
+#endif
+
+ /* Intercept characters for printer controller mode */
+ if (PrinterOf(screen).printer_controlmode == 2) {
+ if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0)
+ continue;
+ }
+
+ /*
+ * VT52 is a little ugly in the one place it has a parameterized
+ * control sequence, since the parameter falls after the character
+ * that denotes the type of sequence.
+ */
+#if OPT_VT52_MODE
+ if (sp->vt52_cup) {
+ if (nparam < NPARAM)
+ param[nparam++] = (int) (c & 0x7f) - 32;
+ if (nparam < 2)
+ continue;
+ sp->vt52_cup = False;
+ if ((row = param[0]) < 0)
+ row = 0;
+ if ((col = param[1]) < 0)
+ col = 0;
+ CursorSet(screen, row, col, xw->flags);
+ sp->parsestate = vt52_table;
+ param[0] = 0;
+ param[1] = 0;
+ continue;
+ }
+#endif
+
+ laststate = sp->nextstate;
+ if (c == ANSI_DEL
+ && sp->parsestate == sp->groundtable
+ && sp->scssize == 96
+ && sp->scstype != 0) {
+ /*
+ * Handle special case of shifts for 96-character sets by checking
+ * if we have a DEL. The other special case for SPACE will always
+ * be printable.
+ */
+ sp->nextstate = CASE_PRINT;
+ } else
+#if OPT_WIDE_CHARS
+ if (c > 255) {
+ /*
+ * The parsing tables all have 256 entries. If we're supporting
+ * wide characters, we handle them by treating them the same as
+ * printing characters.
+ */
+ if (sp->parsestate == sp->groundtable) {
+ sp->nextstate = CASE_PRINT;
+ } else if (sp->parsestate == sos_table) {
+ c &= 0xffff;
+ if (c > 255) {
+ TRACE(("Found code > 255 while in SOS state: %04X\n", c));
+ c = '?';
+ }
+ } else {
+ sp->nextstate = CASE_GROUND_STATE;
+ }
+ } else
+#endif
+ sp->nextstate = sp->parsestate[E2A(c)];
+
+#if OPT_BROKEN_OSC
+ /*
+ * Linux console palette escape sequences start with an OSC, but do
+ * not terminate correctly. Some scripts do not check before writing
+ * them, making xterm appear to hang (it's awaiting a valid string
+ * terminator). Just ignore these if we see them - there's no point
+ * in emulating bad code.
+ */
+ if (screen->brokenLinuxOSC
+ && sp->parsestate == sos_table) {
+ if (sp->string_used) {
+ switch (sp->string_area[0]) {
+ case 'P':
+ if (sp->string_used <= 7)
+ break;
+ /* FALLTHRU */
+ case 'R':
+ illegal_parse(xw, c, sp);
+ TRACE(("Reset to ground state (brokenLinuxOSC)\n"));
+ break;
+ }
+ }
+ }
+#endif
+
+#if OPT_BROKEN_ST
+ /*
+ * Before patch #171, carriage control embedded within an OSC string
+ * would terminate it. Some (buggy, of course) applications rely on
+ * this behavior. Accommodate them by allowing one to compile xterm
+ * and emulate the old behavior.
+ */
+ if (screen->brokenStringTerm
+ && sp->parsestate == sos_table
+ && c < 32) {
+ switch (c) {
+ case ANSI_EOT: /* FALLTHRU */
+ case ANSI_BS: /* FALLTHRU */
+ case ANSI_HT: /* FALLTHRU */
+ case ANSI_LF: /* FALLTHRU */
+ case ANSI_VT: /* FALLTHRU */
+ case ANSI_FF: /* FALLTHRU */
+ case ANSI_CR: /* FALLTHRU */
+ case ANSI_SO: /* FALLTHRU */
+ case ANSI_SI: /* FALLTHRU */
+ case ANSI_XON: /* FALLTHRU */
+ case ANSI_CAN:
+ illegal_parse(xw, c, sp);
+ TRACE(("Reset to ground state (brokenStringTerm)\n"));
+ break;
+ }
+ }
+#endif
+
+#if OPT_C1_PRINT
+ /*
+ * This is not completely foolproof, but will allow an application
+ * with values in the C1 range to use them as printable characters,
+ * provided that they are not intermixed with an escape sequence.
+ */
+ if (screen->c1_printable
+ && (c >= 128 && c < 160)) {
+ sp->nextstate = (sp->parsestate == esc_table
+ ? CASE_ESC_IGNORE
+ : sp->parsestate[E2A(160)]);
+ }
+#endif
+
+#if OPT_WIDE_CHARS
+ /*
+ * If we have a C1 code and the c1_printable flag is not set, simply
+ * ignore it when it was translated from UTF-8. That is because the
+ * value could not have been present as-is in the UTF-8.
+ *
+ * To see that CASE_IGNORE is a consistent value, note that it is
+ * always used for NUL and other uninteresting C0 controls.
+ */
+#if OPT_C1_PRINT
+ if (!screen->c1_printable)
+#endif
+ if (screen->wide_chars
+ && (c >= 128 && c < 160)) {
+ sp->nextstate = CASE_IGNORE;
+ }
+
+ /*
+ * If this character is a different width than the last one, put the
+ * previous text into the buffer and draw it now.
+ */
+ this_is_wide = isWide((int) c);
+ if (this_is_wide != sp->last_was_wide) {
+ WriteNow();
+ }
+#endif
+
+ /*
+ * Accumulate string for printable text. This may be 8/16-bit
+ * characters.
+ */
+ if (sp->nextstate == CASE_PRINT) {
+ SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size);
+ if (new_string == 0) {
+ xtermWarning("Cannot allocate %lu bytes for printable text\n",
+ (unsigned long) new_length);
+ continue;
+ }
+#if OPT_VT52_MODE
+ /*
+ * Strip output text to 7-bits for VT52. We should do this for
+ * VT100 also (which is a 7-bit device), but xterm has been
+ * doing this for so long we shouldn't change this behavior.
+ */
+ if (screen->vtXX_level < 1)
+ c &= 0x7f;
+#endif
+ sp->print_area = new_string;
+ sp->print_size = new_length;
+ sp->print_area[sp->print_used++] = (IChar) c;
+ sp->lastchar = thischar = (int) c;
+#if OPT_WIDE_CHARS
+ sp->last_was_wide = this_is_wide;
+#endif
+ if (morePtyData(screen, VTbuffer)) {
+ continue;
+ }
+ }
+
+ if (sp->nextstate == CASE_PRINT
+ || (laststate == CASE_PRINT && sp->print_used)) {
+ WriteNow();
+ }
+
+ /*
+ * Accumulate string for APC, DCS, PM, OSC, SOS controls
+ * This should always be 8-bit characters.
+ */
+ if (sp->parsestate == sos_table) {
+ SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size);
+ if (new_string == 0) {
+ xtermWarning("Cannot allocate %lu bytes for string mode %d\n",
+ (unsigned long) new_length, sp->string_mode);
+ continue;
+ }
+#if OPT_WIDE_CHARS
+ /*
+ * We cannot display codes above 255, but let's try to
+ * accommodate the application a little by not aborting the
+ * string.
+ */
+ if ((c & 0xffff) > 255) {
+ sp->nextstate = CASE_PRINT;
+ c = '?';
+ }
+#endif
+ sp->string_area = new_string;
+ sp->string_size = new_length;
+ sp->string_area[(sp->string_used)++] = CharOf(c);
+ } else if (sp->parsestate != esc_table) {
+ /* if we were accumulating, we're not any more */
+ sp->string_mode = 0;
+ sp->string_used = 0;
+ }
+
+ TRACE(("parse %04X -> %d %s\n", c, sp->nextstate, which_table(sp->parsestate)));
+
+ switch (sp->nextstate) {
+ case CASE_PRINT:
+ TRACE(("CASE_PRINT - printable characters\n"));
+ break;
+
+ case CASE_GROUND_STATE:
+ TRACE(("CASE_GROUND_STATE - exit ignore mode\n"));
+ ResetState(sp);
+ break;
+
+ case CASE_IGNORE:
+ TRACE(("CASE_IGNORE - Ignore character %02X\n", c));
+ break;
+
+ case CASE_ENQ:
+ TRACE(("CASE_ENQ - answerback\n"));
+ for (count = 0; screen->answer_back[count] != 0; count++)
+ unparseputc(xw, screen->answer_back[count]);
+ unparse_end(xw);
+ break;
+
+ case CASE_BELL:
+ TRACE(("CASE_BELL - bell\n"));
+ if (sp->string_mode == ANSI_OSC) {
+ if (sp->string_used)
+ sp->string_area[--(sp->string_used)] = '\0';
+ do_osc(xw, sp->string_area, sp->string_used, (int) c);
+ ResetState(sp);
+ } else {
+ /* bell */
+ Bell(xw, XkbBI_TerminalBell, 0);
+ }
+ break;
+
+ case CASE_BS:
+ TRACE(("CASE_BS - backspace\n"));
+ CursorBack(xw, 1);
+ break;
+
+ case CASE_CR:
+ TRACE(("CASE_CR\n"));
+ CarriageReturn(xw);
+ break;
+
+ case CASE_ESC:
+ if_OPT_VT52_MODE(screen, {
+ sp->parsestate = vt52_esc_table;
+ break;
+ });
+ sp->parsestate = esc_table;
+ break;
+
+#if OPT_VT52_MODE
+ case CASE_VT52_CUP:
+ TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n"));
+ sp->vt52_cup = True;
+ nparam = 0;
+ break;
+
+ case CASE_VT52_IGNORE:
+ TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n"));
+ sp->parsestate = vt52_ignore_table;
+ break;
+#endif
+
+ case CASE_VMOT:
+ TRACE(("CASE_VMOT\n"));
+ /*
+ * form feed, line feed, vertical tab
+ */
+ xtermAutoPrint(xw, c);
+ xtermIndex(xw, 1);
+ if (xw->flags & LINEFEED)
+ CarriageReturn(xw);
+ else
+ do_xevents();
+ break;
+
+ case CASE_CBT:
+ TRACE(("CASE_CBT\n"));
+ /* cursor backward tabulation */
+ if ((count = param[0]) == DEFAULT)
+ count = 1;
+ while ((count-- > 0)
+ && (TabToPrevStop(xw))) ;
+ ResetState(sp);
+ break;
+
+ case CASE_CHT:
+ TRACE(("CASE_CHT\n"));
+ /* cursor forward tabulation */
+ if ((count = param[0]) == DEFAULT)
+ count = 1;
+ while ((count-- > 0)
+ && (TabToNextStop(xw))) ;
+ ResetState(sp);
+ break;
+
+ case CASE_TAB:
+ /* tab */
+ TabToNextStop(xw);
+ break;
+
+ case CASE_SI:
+ screen->curgl = 0;
+ if_OPT_VT52_MODE(screen, {
+ ResetState(sp);
+ });
+ break;
+
+ case CASE_SO:
+ screen->curgl = 1;
+ if_OPT_VT52_MODE(screen, {
+ ResetState(sp);
+ });
+ break;
+
+ case CASE_DECDHL:
+ xterm_DECDHL(xw, c == '3');
+ ResetState(sp);
+ break;
+
+ case CASE_DECSWL:
+ xterm_DECSWL(xw);
+ ResetState(sp);
+ break;
+
+ case CASE_DECDWL:
+ xterm_DECDWL(xw);
+ ResetState(sp);
+ break;
+
+ case CASE_SCR_STATE:
+ /* enter scr state */
+ sp->parsestate = scrtable;
+ break;
+
+ case CASE_SCS0_STATE:
+ /* enter scs state 0 */
+ select_charset(sp, 0, 94);
+ break;
+
+ case CASE_SCS1_STATE:
+ /* enter scs state 1 */
+ select_charset(sp, 1, 94);
+ break;
+
+ case CASE_SCS2_STATE:
+ /* enter scs state 2 */
+ select_charset(sp, 2, 94);
+ break;
+
+ case CASE_SCS3_STATE:
+ /* enter scs state 3 */
+ select_charset(sp, 3, 94);
+ break;
+
+ case CASE_SCS1A_STATE:
+ /* enter scs state 1 */
+ select_charset(sp, 1, 96);
+ break;
+
+ case CASE_SCS2A_STATE:
+ /* enter scs state 2 */
+ select_charset(sp, 2, 96);
+ break;
+
+ case CASE_SCS3A_STATE:
+ /* enter scs state 3 */
+ select_charset(sp, 3, 96);
+ break;
+
+ case CASE_ESC_IGNORE:
+ /* unknown escape sequence */
+ sp->parsestate = eigtable;
+ break;
+
+ case CASE_ESC_DIGIT:
+ /* digit in csi or dec mode */
+ if (nparam > 0) {
+ if ((row = param[nparam - 1]) == DEFAULT)
+ row = 0;
+ param[nparam - 1] = (10 * row) + ((int) c - '0');
+ if (param[nparam - 1] > 65535)
+ param[nparam - 1] = 65535;
+ if (sp->parsestate == csi_table)
+ sp->parsestate = csi2_table;
+ }
+ break;
+
+ case CASE_ESC_SEMI:
+ /* semicolon in csi or dec mode */
+ if (nparam < NPARAM)
+ param[nparam++] = DEFAULT;
+ if (sp->parsestate == csi_table)
+ sp->parsestate = csi2_table;
+ break;
+
+ case CASE_DEC_STATE:
+ /* enter dec mode */
+ sp->parsestate = dec_table;
+ break;
+
+ case CASE_DEC2_STATE:
+ /* enter dec2 mode */
+ sp->parsestate = dec2_table;
+ break;
+
+ case CASE_DEC3_STATE:
+ /* enter dec3 mode */
+ sp->parsestate = dec3_table;
+ break;
+
+ case CASE_ICH:
+ TRACE(("CASE_ICH - insert char\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ InsertChar(xw, (unsigned) row);
+ ResetState(sp);
+ break;
+
+ case CASE_CUU:
+ TRACE(("CASE_CUU - cursor up\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ CursorUp(screen, row);
+ ResetState(sp);
+ break;
+
+ case CASE_CUD:
+ TRACE(("CASE_CUD - cursor down\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ CursorDown(screen, row);
+ ResetState(sp);
+ break;
+
+ case CASE_CUF:
+ TRACE(("CASE_CUF - cursor forward\n"));
+ if ((col = param[0]) < 1)
+ col = 1;
+ CursorForward(xw, col);
+ ResetState(sp);
+ break;
+
+ case CASE_CUB:
+ TRACE(("CASE_CUB - cursor backward\n"));
+ if ((col = param[0]) < 1)
+ col = 1;
+ CursorBack(xw, col);
+ ResetState(sp);
+ break;
+
+ case CASE_CUP:
+ TRACE(("CASE_CUP - cursor position\n"));
+ if_OPT_XMC_GLITCH(screen, {
+ Jump_XMC(xw);
+ });
+ if ((row = param[0]) < 1)
+ row = 1;
+ if (nparam < 2 || (col = param[1]) < 1)
+ col = 1;
+ CursorSet(screen, row - 1, col - 1, xw->flags);
+ ResetState(sp);
+ break;
+
+ case CASE_VPA:
+ TRACE(("CASE_VPA - vertical position absolute\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ CursorSet(screen, row - 1, CursorCol(xw), xw->flags);
+ ResetState(sp);
+ break;
+
+ case CASE_HPA:
+ TRACE(("CASE_HPA - horizontal position absolute\n"));
+ if ((col = param[0]) < 1)
+ col = 1;
+ CursorSet(screen, CursorRow(xw), col - 1, xw->flags);
+ ResetState(sp);
+ break;
+
+ case CASE_VPR:
+ TRACE(("CASE_VPR - vertical position relative\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ CursorSet(screen, CursorRow(xw) + row, CursorCol(xw), xw->flags);
+ ResetState(sp);
+ break;
+
+ case CASE_HPR:
+ TRACE(("CASE_HPR - horizontal position relative\n"));
+ if ((col = param[0]) < 1)
+ col = 1;
+ CursorSet(screen, CursorRow(xw), CursorCol(xw) + col, xw->flags);
+ ResetState(sp);
+ break;
+
+ case CASE_HP_BUGGY_LL:
+ TRACE(("CASE_HP_BUGGY_LL\n"));
+ /* Some HP-UX applications have the bug that they
+ assume ESC F goes to the lower left corner of
+ the screen, regardless of what terminfo says. */
+ if (screen->hp_ll_bc)
+ CursorSet(screen, screen->max_row, 0, xw->flags);
+ ResetState(sp);
+ break;
+
+ case CASE_ED:
+ TRACE(("CASE_ED - erase display\n"));
+ do_erase_display(xw, param[0], OFF_PROTECT);
+ ResetState(sp);
+ break;
+
+ case CASE_EL:
+ TRACE(("CASE_EL - erase line\n"));
+ do_erase_line(xw, param[0], OFF_PROTECT);
+ ResetState(sp);
+ break;
+
+ case CASE_ECH:
+ TRACE(("CASE_ECH - erase char\n"));
+ /* ECH */
+ ClearRight(xw, param[0] < 1 ? 1 : param[0]);
+ ResetState(sp);
+ break;
+
+ case CASE_IL:
+ TRACE(("CASE_IL - insert line\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ set_cur_col(screen, ScrnLeftMargin(xw));
+ InsertLine(xw, row);
+ ResetState(sp);
+ break;
+
+ case CASE_DL:
+ TRACE(("CASE_DL - delete line\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ set_cur_col(screen, ScrnLeftMargin(xw));
+ DeleteLine(xw, row);
+ ResetState(sp);
+ break;
+
+ case CASE_DCH:
+ TRACE(("CASE_DCH - delete char\n"));
+ if ((row = param[0]) < 1)
+ row = 1;
+ DeleteChar(xw, (unsigned) row);
+ ResetState(sp);
+ break;
+
+ case CASE_TRACK_MOUSE:
+ /*
+ * A single parameter other than zero is always scroll-down.
+ * A zero-parameter is used to reset the mouse mode, and is
+ * not useful for scrolling anyway.
+ */
+ if (nparam > 1 || param[0] == 0) {
+ CELL start;
+
+ TRACE(("CASE_TRACK_MOUSE\n"));
+ /* Track mouse as long as in window and between
+ * specified rows
+ */
+ start.row = one_if_default(2) - 1;
+ start.col = param[1] - 1;
+ TrackMouse(xw,
+ param[0],
+ &start,
+ param[3] - 1, param[4] - 2);
+ } else {
+ TRACE(("CASE_SD - scroll down\n"));
+ /* SD */
+ if ((count = param[0]) < 1)
+ count = 1;
+ RevScroll(xw, count);
+ do_xevents();
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECID:
+ TRACE(("CASE_DECID\n"));
+ if_OPT_VT52_MODE(screen, {
+ unparseputc(xw, ANSI_ESC);
+ unparseputc(xw, '/');
+ unparseputc(xw, 'Z');
+ unparse_end(xw);
+ ResetState(sp);
+ break;
+ });
+ param[0] = DEFAULT; /* Default ID parameter */
+ /* FALLTHRU */
+ case CASE_DA1:
+ TRACE(("CASE_DA1\n"));
+ if (param[0] <= 0) { /* less than means DEFAULT */
+ count = 0;
+ init_reply(ANSI_CSI);
+ reply.a_pintro = '?';
+
+ /* The first param corresponds to the highest
+ * operating level (i.e., service level) of the
+ * emulation. A DEC terminal can be setup to
+ * respond with a different DA response, but
+ * there's no control sequence that modifies this.
+ * We set it via a resource.
+ */
+ if (screen->terminal_id < 200) {
+ switch (screen->terminal_id) {
+ case 102:
+ reply.a_param[count++] = 6; /* VT102 */
+ break;
+ case 101:
+ reply.a_param[count++] = 1; /* VT101 */
+ reply.a_param[count++] = 0; /* no options */
+ break;
+ default: /* VT100 */
+ reply.a_param[count++] = 1; /* VT100 */
+ reply.a_param[count++] = 2; /* AVO */
+ break;
+ }
+ } else {
+ reply.a_param[count++] = (ParmType) (60
+ + screen->terminal_id
+ / 100);
+ reply.a_param[count++] = 1; /* 132-columns */
+ reply.a_param[count++] = 2; /* printer */
+ reply.a_param[count++] = 6; /* selective-erase */
+#if OPT_SUNPC_KBD
+ if (xw->keyboard.type == keyboardIsVT220)
+#endif
+ reply.a_param[count++] = 8; /* user-defined-keys */
+ reply.a_param[count++] = 9; /* national replacement charsets */
+ reply.a_param[count++] = 15; /* technical characters */
+ if (screen->terminal_id >= 400) {
+ reply.a_param[count++] = 18; /* windowing capability */
+ reply.a_param[count++] = 21; /* horizontal scrolling */
+ }
+ if_OPT_ISO_COLORS(screen, {
+ reply.a_param[count++] = 22; /* ANSI color, VT525 */
+ });
+#if OPT_DEC_LOCATOR
+ reply.a_param[count++] = 29; /* ANSI text locator */
+#endif
+ }
+ reply.a_nparam = (ParmType) count;
+ reply.a_inters = 0;
+ reply.a_final = 'c';
+ unparseseq(xw, &reply);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DA2:
+ TRACE(("CASE_DA2\n"));
+ if (param[0] <= 0) { /* less than means DEFAULT */
+ count = 0;
+ init_reply(ANSI_CSI);
+ reply.a_pintro = '>';
+
+ if (screen->terminal_id >= 200) {
+ switch (screen->terminal_id) {
+ case 220:
+ default:
+ reply.a_param[count++] = 1; /* VT220 */
+ break;
+ case 240:
+ /* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */
+ reply.a_param[count++] = 2; /* VT240 */
+ break;
+ case 320:
+ /* http://www.vt100.net/docs/vt320-uu/appendixe.html */
+ reply.a_param[count++] = 24; /* VT320 */
+ break;
+ case 330:
+ reply.a_param[count++] = 18; /* VT330 */
+ break;
+ case 340:
+ reply.a_param[count++] = 19; /* VT340 */
+ break;
+ case 420:
+ reply.a_param[count++] = 41; /* VT420 */
+ break;
+ case 510:
+ /* http://www.vt100.net/docs/vt510-rm/DA2 */
+ reply.a_param[count++] = 61; /* VT510 */
+ break;
+ case 520:
+ reply.a_param[count++] = 64; /* VT520 */
+ break;
+ case 525:
+ reply.a_param[count++] = 65; /* VT525 */
+ break;
+ }
+ } else {
+ reply.a_param[count++] = 0; /* VT100 (nonstandard) */
+ }
+ reply.a_param[count++] = XTERM_PATCH; /* Version */
+ reply.a_param[count++] = 0; /* options (none) */
+ reply.a_nparam = (ParmType) count;
+ reply.a_inters = 0;
+ reply.a_final = 'c';
+ unparseseq(xw, &reply);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECRPTUI:
+ TRACE(("CASE_DECRPTUI\n"));
+ if ((screen->vtXX_level >= 4)
+ && (param[0] <= 0)) { /* less than means DEFAULT */
+ unparseputc1(xw, ANSI_DCS);
+ unparseputc(xw, '!');
+ unparseputc(xw, '|');
+ unparseputc(xw, '0');
+ unparseputc1(xw, ANSI_ST);
+ unparse_end(xw);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_TBC:
+ TRACE(("CASE_TBC - tab clear\n"));
+ if ((row = param[0]) <= 0) /* less than means default */
+ TabClear(xw->tabs, screen->cur_col);
+ else if (row == 3)
+ TabZonk(xw->tabs);
+ ResetState(sp);
+ break;
+
+ case CASE_SET:
+ TRACE(("CASE_SET - set mode\n"));
+ ansi_modes(xw, bitset);
+ ResetState(sp);
+ break;
+
+ case CASE_RST:
+ TRACE(("CASE_RST - reset mode\n"));
+ ansi_modes(xw, bitclr);
+ ResetState(sp);
+ break;
+
+ case CASE_SGR:
+ for (row = 0; row < nparam; ++row) {
+ if_OPT_XMC_GLITCH(screen, {
+ Mark_XMC(xw, param[row]);
+ });
+ TRACE(("CASE_SGR %d\n", param[row]));
+ switch (param[row]) {
+ case DEFAULT:
+ case 0:
+ UIntClr(xw->flags,
+ (INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE));
+ if_OPT_ISO_COLORS(screen, {
+ reset_SGR_Colors(xw);
+ });
+ break;
+ case 1: /* Bold */
+ xw->flags |= BOLD;
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ break;
+ case 5: /* Blink */
+ xw->flags |= BLINK;
+ StartBlinking(screen);
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ break;
+ case 4: /* Underscore */
+ xw->flags |= UNDERLINE;
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ break;
+ case 7:
+ xw->flags |= INVERSE;
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedBG(xw);
+ });
+ break;
+ case 8:
+ xw->flags |= INVISIBLE;
+ break;
+ case 22: /* reset 'bold' */
+ UIntClr(xw->flags, BOLD);
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ break;
+ case 24:
+ UIntClr(xw->flags, UNDERLINE);
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ break;
+ case 25: /* reset 'blink' */
+ UIntClr(xw->flags, BLINK);
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ break;
+ case 27:
+ UIntClr(xw->flags, INVERSE);
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedBG(xw);
+ });
+ break;
+ case 28:
+ UIntClr(xw->flags, INVISIBLE);
+ break;
+ case 30:
+ case 31:
+ case 32:
+ case 33:
+ case 34:
+ case 35:
+ case 36:
+ case 37:
+ if_OPT_ISO_COLORS(screen, {
+ xw->sgr_foreground = (param[row] - 30);
+ xw->sgr_extended = False;
+ setExtendedFG(xw);
+ });
+ break;
+ case 38:
+ /* This is more complicated than I'd
+ like, but it should properly eat all
+ the parameters for unsupported modes
+ */
+ if_OPT_ISO_COLORS(screen, {
+ row++;
+ if (row < nparam) {
+ switch (param[row]) {
+ case 5:
+ row++;
+ if (row < nparam &&
+ param[row] < NUM_ANSI_COLORS) {
+ xw->sgr_foreground = param[row];
+ xw->sgr_extended = True;
+ setExtendedFG(xw);
+ }
+ break;
+ default:
+ row += 7;
+ break;
+ }
+ }
+ });
+ break;
+ case 39:
+ if_OPT_ISO_COLORS(screen, {
+ reset_SGR_Foreground(xw);
+ });
+ break;
+ case 40:
+ case 41:
+ case 42:
+ case 43:
+ case 44:
+ case 45:
+ case 46:
+ case 47:
+ if_OPT_ISO_COLORS(screen, {
+ xw->sgr_background = (param[row] - 40);
+ setExtendedBG(xw);
+ });
+ break;
+ case 48:
+ if_OPT_ISO_COLORS(screen, {
+ row++;
+ if (row < nparam) {
+ switch (param[row]) {
+ case 5:
+ row++;
+ if (row < nparam &&
+ param[row] < NUM_ANSI_COLORS) {
+ xw->sgr_background = param[row];
+ setExtendedBG(xw);
+ }
+ break;
+ default:
+ row += 7;
+ break;
+ }
+ }
+ });
+ break;
+ case 49:
+ if_OPT_ISO_COLORS(screen, {
+ reset_SGR_Background(xw);
+ });
+ break;
+ case 90:
+ case 91:
+ case 92:
+ case 93:
+ case 94:
+ case 95:
+ case 96:
+ case 97:
+ if_OPT_AIX_COLORS(screen, {
+ xw->sgr_foreground = (param[row] - 90 + 8);
+ xw->sgr_extended = False;
+ setExtendedFG(xw);
+ });
+ break;
+ case 100:
+#if !OPT_AIX_COLORS
+ if_OPT_ISO_COLORS(screen, {
+ reset_SGR_Foreground(xw);
+ reset_SGR_Background(xw);
+ });
+ break;
+#endif
+ case 101:
+ case 102:
+ case 103:
+ case 104:
+ case 105:
+ case 106:
+ case 107:
+ if_OPT_AIX_COLORS(screen, {
+ xw->sgr_background = (param[row] - 100 + 8);
+ setExtendedBG(xw);
+ });
+ break;
+ }
+ }
+ ResetState(sp);
+ break;
+
+ /* DSR (except for the '?') is a superset of CPR */
+ case CASE_DSR:
+ sp->private_function = True;
+
+ /* FALLTHRU */
+ case CASE_CPR:
+ TRACE(("CASE_DSR - device status report\n"));
+ count = 0;
+ init_reply(ANSI_CSI);
+ reply.a_pintro = CharOf(sp->private_function ? '?' : 0);
+ reply.a_inters = 0;
+ reply.a_final = 'n';
+
+ switch (param[0]) {
+ case 5:
+ TRACE(("...request operating status\n"));
+ /* operating status */
+ reply.a_param[count++] = 0; /* (no malfunction ;-) */
+ break;
+ case 6:
+ TRACE(("...request %s\n",
+ (sp->private_function
+ ? "DECXCPR"
+ : "CPR")));
+ /* CPR */
+ /* DECXCPR (with page=1) */
+ reply.a_param[count++] = (ParmType) (screen->cur_row + 1);
+ reply.a_param[count++] = (ParmType) (screen->cur_col + 1);
+ if (sp->private_function
+ && screen->vtXX_level >= 4) { /* VT420 */
+ reply.a_param[count++] = 1;
+ }
+ reply.a_final = 'R';
+ break;
+ case 15:
+ TRACE(("...request printer status\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 2) { /* VT220 */
+ reply.a_param[count++] = 13; /* implement printer */
+ }
+ break;
+ case 25:
+ TRACE(("...request UDK status\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 2) { /* VT220 */
+ reply.a_param[count++] = 20; /* UDK always unlocked */
+ }
+ break;
+ case 26:
+ TRACE(("...request keyboard status\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 2) { /* VT220 */
+ reply.a_param[count++] = 27;
+ reply.a_param[count++] = 1; /* North American */
+ if (screen->vtXX_level >= 4) { /* VT420 */
+ reply.a_param[count++] = 0; /* ready */
+ reply.a_param[count++] = 0; /* LK201 */
+ }
+ }
+ break;
+ case 53:
+ TRACE(("...request locator status\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 2) { /* VT220 */
+#if OPT_DEC_LOCATOR
+ reply.a_param[count++] = 50; /* locator ready */
+#else
+ reply.a_param[count++] = 53; /* no locator */
+#endif
+ }
+ break;
+ case 62:
+ TRACE(("...request DECMSR - macro space\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 4) { /* VT420 */
+ reply.a_pintro = 0;
+ reply.a_radix[count] = 16; /* no data */
+ reply.a_param[count++] = 0; /* no space for macros */
+ reply.a_inters = '*';
+ reply.a_final = '{';
+ }
+ break;
+ case 63:
+ TRACE(("...request DECCKSR - memory checksum\n"));
+ /* DECCKSR - Memory checksum */
+ if (sp->private_function
+ && screen->vtXX_level >= 4) { /* VT420 */
+ init_reply(ANSI_DCS);
+ reply.a_param[count++] = (ParmType) param[1]; /* PID */
+ reply.a_delim = "!~"; /* delimiter */
+ reply.a_radix[count] = 16; /* use hex */
+ reply.a_param[count++] = 0; /* no data */
+ }
+ break;
+ case 75:
+ TRACE(("...request data integrity\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 4) { /* VT420 */
+ reply.a_param[count++] = 70; /* no errors */
+ }
+ break;
+ case 85:
+ TRACE(("...request multi-session configuration\n"));
+ if (sp->private_function
+ && screen->vtXX_level >= 4) { /* VT420 */
+ reply.a_param[count++] = 83; /* not configured */
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ((reply.a_nparam = (ParmType) count) != 0)
+ unparseseq(xw, &reply);
+
+ ResetState(sp);
+ sp->private_function = False;
+ break;
+
+ case CASE_MC:
+ TRACE(("CASE_MC - media control\n"));
+ xtermMediaControl(xw, param[0], False);
+ ResetState(sp);
+ break;
+
+ case CASE_DEC_MC:
+ TRACE(("CASE_DEC_MC - DEC media control\n"));
+ xtermMediaControl(xw, param[0], True);
+ ResetState(sp);
+ break;
+
+ case CASE_HP_MEM_LOCK:
+ case CASE_HP_MEM_UNLOCK:
+ TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK)
+ ? "CASE_HP_MEM_LOCK"
+ : "CASE_HP_MEM_UNLOCK")));
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ if (sp->parsestate[c] == CASE_HP_MEM_LOCK)
+ set_tb_margins(screen, screen->cur_row, screen->bot_marg);
+ else
+ set_tb_margins(screen, 0, screen->bot_marg);
+ ResetState(sp);
+ break;
+
+ case CASE_DECSTBM:
+ TRACE(("CASE_DECSTBM - set scrolling region\n"));
+ {
+ int top;
+ int bot;
+ if ((top = param[0]) < 1)
+ top = 1;
+ if (nparam < 2 || (bot = param[1]) == DEFAULT
+ || bot > MaxRows(screen)
+ || bot == 0)
+ bot = MaxRows(screen);
+ if (bot > top) {
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ set_tb_margins(screen, top - 1, bot - 1);
+ CursorSet(screen, 0, 0, xw->flags);
+ }
+ ResetState(sp);
+ }
+ break;
+
+ case CASE_DECREQTPARM:
+ TRACE(("CASE_DECREQTPARM\n"));
+ if (screen->terminal_id < 200) { /* VT102 */
+ if ((row = param[0]) == DEFAULT)
+ row = 0;
+ if (row == 0 || row == 1) {
+ init_reply(ANSI_CSI);
+ reply.a_pintro = 0;
+ reply.a_nparam = 7;
+ reply.a_param[0] = (ParmType) (row + 2);
+ reply.a_param[1] = 1; /* no parity */
+ reply.a_param[2] = 1; /* eight bits */
+ reply.a_param[3] = 128; /* transmit 38.4k baud */
+ reply.a_param[4] = 128; /* receive 38.4k baud */
+ reply.a_param[5] = 1; /* clock multiplier ? */
+ reply.a_param[6] = 0; /* STP flags ? */
+ reply.a_inters = 0;
+ reply.a_final = 'x';
+ unparseseq(xw, &reply);
+ }
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSET:
+ /* DECSET */
+#if OPT_VT52_MODE
+ if (screen->vtXX_level != 0)
+#endif
+ dpmodes(xw, bitset);
+ ResetState(sp);
+#if OPT_TEK4014
+ if (TEK4014_ACTIVE(xw))
+ return False;
+#endif
+ break;
+
+ case CASE_DECRST:
+ /* DECRST */
+ dpmodes(xw, bitclr);
+ init_groundtable(screen, sp);
+ ResetState(sp);
+ break;
+
+ case CASE_DECALN:
+ TRACE(("CASE_DECALN - alignment test\n"));
+ if (screen->cursor_state)
+ HideCursor();
+ reset_margins(screen);
+ CursorSet(screen, 0, 0, xw->flags);
+ xtermParseRect(xw, 0, 0, &myRect);
+ ScrnFillRectangle(xw, &myRect, 'E', 0, False);
+ ResetState(sp);
+ break;
+
+ case CASE_GSETS:
+ TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c));
+ if (screen->vtXX_level != 0)
+ screen->gsets[sp->scstype] = CharOf(c);
+ ResetState(sp);
+ break;
+
+ case CASE_ANSI_SC:
+ if (IsLeftRightMode(xw)) {
+ int left;
+ int right;
+
+ TRACE(("CASE_DECSLRM - set left and right margin\n"));
+ if ((left = param[0]) < 1)
+ left = 1;
+ if (nparam < 2 || (right = param[1]) == DEFAULT
+ || right > MaxCols(screen)
+ || right == 0)
+ right = MaxCols(screen);
+ if (right > left) {
+ set_lr_margins(screen, left - 1, right - 1);
+ CursorSet(screen, 0, 0, xw->flags);
+ }
+ } else {
+ TRACE(("CASE_ANSI_SC - save cursor\n"));
+ CursorSave(xw);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSC:
+ TRACE(("CASE_DECSC - save cursor\n"));
+ CursorSave(xw);
+ ResetState(sp);
+ break;
+
+ case CASE_ANSI_RC:
+ case CASE_DECRC:
+ TRACE(("CASE_%sRC - restore cursor\n",
+ (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_"));
+ CursorRestore(xw);
+ if_OPT_ISO_COLORS(screen, {
+ setExtendedFG(xw);
+ });
+ ResetState(sp);
+ break;
+
+ case CASE_DECKPAM:
+ TRACE(("CASE_DECKPAM\n"));
+ xw->keyboard.flags |= MODE_DECKPAM;
+ update_appkeypad();
+ ResetState(sp);
+ break;
+
+ case CASE_DECKPNM:
+ TRACE(("CASE_DECKPNM\n"));
+ UIntClr(xw->keyboard.flags, MODE_DECKPAM);
+ update_appkeypad();
+ ResetState(sp);
+ break;
+
+ case CASE_CSI_QUOTE_STATE:
+ sp->parsestate = csi_quo_table;
+ break;
+
+#if OPT_BLINK_CURS
+ case CASE_CSI_SPACE_STATE:
+ sp->parsestate = csi_sp_table;
+ break;
+
+ case CASE_DECSCUSR:
+ TRACE(("CASE_DECSCUSR\n"));
+ {
+ Boolean change = True;
+ Boolean blinks = screen->cursor_blink_esc;
+
+ HideCursor();
+
+ switch (param[0]) {
+ case 0:
+ case 1:
+ case DEFAULT:
+ /* blinking block */
+ screen->cursor_underline = False;
+ blinks = True;
+ break;
+ case 2:
+ /* steady block */
+ screen->cursor_underline = False;
+ blinks = False;
+ break;
+ case 3:
+ /* blinking underline */
+ screen->cursor_underline = True;
+ blinks = True;
+ break;
+ case 4:
+ /* steady underline */
+ screen->cursor_underline = True;
+ blinks = False;
+ break;
+ default:
+ change = False;
+ break;
+ }
+
+ if (change) {
+ xtermSetCursorBox(screen);
+ screen->cursor_blink_esc = blinks;
+ UpdateCursorBlink(screen);
+ }
+ }
+ ResetState(sp);
+ break;
+#endif
+
+#if OPT_SCROLL_LOCK
+ case CASE_DECLL:
+ TRACE(("CASE_DECLL\n"));
+ if (nparam > 0) {
+ for (count = 0; count < nparam; ++count) {
+ switch (param[count]) {
+ case 0:
+ case DEFAULT:
+ xtermClearLEDs(screen);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ xtermShowLED(screen, (Cardinal) param[count], True);
+ break;
+ case 21:
+ case 22:
+ case 23:
+ xtermShowLED(screen, (Cardinal) (param[count] - 20), True);
+ break;
+ }
+ }
+ } else {
+ xtermClearLEDs(screen);
+ }
+ ResetState(sp);
+ break;
+#endif
+
+#if OPT_VT52_MODE
+ case CASE_VT52_FINISH:
+ TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n",
+ screen->terminal_id,
+ screen->vtXX_level));
+ if (screen->terminal_id >= 100
+ && screen->vtXX_level == 0) {
+ sp->groundtable =
+ sp->parsestate = ansi_table;
+ /*
+ * On restore, the terminal does not recognize DECRQSS for
+ * DECSCL (per vttest).
+ */
+ screen->vtXX_level = 1;
+ screen->curgl = screen->vt52_save_curgl;
+ screen->curgr = screen->vt52_save_curgr;
+ screen->curss = screen->vt52_save_curss;
+ memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets));
+ }
+ break;
+#endif
+
+ case CASE_ANSI_LEVEL_1:
+ TRACE(("CASE_ANSI_LEVEL_1\n"));
+ set_ansi_conformance(screen, 1);
+ ResetState(sp);
+ break;
+
+ case CASE_ANSI_LEVEL_2:
+ TRACE(("CASE_ANSI_LEVEL_2\n"));
+ set_ansi_conformance(screen, 2);
+ ResetState(sp);
+ break;
+
+ case CASE_ANSI_LEVEL_3:
+ TRACE(("CASE_ANSI_LEVEL_3\n"));
+ set_ansi_conformance(screen, 3);
+ ResetState(sp);
+ break;
+
+ case CASE_DECSCL:
+ TRACE(("CASE_DECSCL(%d,%d)\n", param[0], param[1]));
+ /*
+ * This changes the emulation level, and is not recognized by
+ * VT100s.
+ */
+ if (screen->terminal_id >= 200) {
+ /*
+ * Disallow unrecognized parameters, as well as attempts to set
+ * the operating level higher than the given terminal-id.
+ */
+ if (param[0] >= 61
+ && param[0] <= 60 + (screen->terminal_id / 100)) {
+ /*
+ * VT300, VT420, VT520 manuals claim that DECSCL does a
+ * hard reset (RIS). VT220 manual states that it is a soft
+ * reset. Perhaps both are right (unlikely). Kermit says
+ * it's soft.
+ */
+ ReallyReset(xw, False, False);
+ init_parser(xw, sp);
+ screen->vtXX_level = param[0] - 60;
+ if (param[0] > 61) {
+ switch (zero_if_default(1)) {
+ case 1:
+ show_8bit_control(False);
+ break;
+ case 0:
+ case 2:
+ show_8bit_control(True);
+ break;
+ }
+ }
+ }
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSCA:
+ TRACE(("CASE_DECSCA\n"));
+ screen->protected_mode = DEC_PROTECT;
+ if (param[0] <= 0 || param[0] == 2) {
+ UIntClr(xw->flags, PROTECTED);
+ TRACE(("...clear PROTECTED\n"));
+ } else if (param[0] == 1) {
+ xw->flags |= PROTECTED;
+ TRACE(("...set PROTECTED\n"));
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSED:
+ TRACE(("CASE_DECSED\n"));
+ do_erase_display(xw, param[0], DEC_PROTECT);
+ ResetState(sp);
+ break;
+
+ case CASE_DECSEL:
+ TRACE(("CASE_DECSEL\n"));
+ do_erase_line(xw, param[0], DEC_PROTECT);
+ ResetState(sp);
+ break;
+
+ case CASE_ST:
+ TRACE(("CASE_ST: End of String (%lu bytes)\n", (unsigned long) sp->string_used));
+ ResetState(sp);
+ if (!sp->string_used)
+ break;
+ sp->string_area[--(sp->string_used)] = '\0';
+ switch (sp->string_mode) {
+ case ANSI_APC:
+ /* ignored */
+ break;
+ case ANSI_DCS:
+ do_dcs(xw, sp->string_area, sp->string_used);
+ break;
+ case ANSI_OSC:
+ do_osc(xw, sp->string_area, sp->string_used, ANSI_ST);
+ break;
+ case ANSI_PM:
+ /* ignored */
+ break;
+ case ANSI_SOS:
+ /* ignored */
+ break;
+ }
+ break;
+
+ case CASE_SOS:
+ TRACE(("CASE_SOS: Start of String\n"));
+ if (ParseSOS(screen)) {
+ sp->string_mode = ANSI_SOS;
+ sp->parsestate = sos_table;
+ } else {
+ illegal_parse(xw, c, sp);
+ }
+ break;
+
+ case CASE_PM:
+ TRACE(("CASE_PM: Privacy Message\n"));
+ if (ParseSOS(screen)) {
+ sp->string_mode = ANSI_PM;
+ sp->parsestate = sos_table;
+ } else {
+ illegal_parse(xw, c, sp);
+ }
+ break;
+
+ case CASE_DCS:
+ TRACE(("CASE_DCS: Device Control String\n"));
+ sp->string_mode = ANSI_DCS;
+ sp->parsestate = sos_table;
+ break;
+
+ case CASE_APC:
+ TRACE(("CASE_APC: Application Program Command\n"));
+ if (ParseSOS(screen)) {
+ sp->string_mode = ANSI_APC;
+ sp->parsestate = sos_table;
+ } else {
+ illegal_parse(xw, c, sp);
+ }
+ break;
+
+ case CASE_SPA:
+ TRACE(("CASE_SPA - start protected area\n"));
+ screen->protected_mode = ISO_PROTECT;
+ xw->flags |= PROTECTED;
+ ResetState(sp);
+ break;
+
+ case CASE_EPA:
+ TRACE(("CASE_EPA - end protected area\n"));
+ UIntClr(xw->flags, PROTECTED);
+ ResetState(sp);
+ break;
+
+ case CASE_SU:
+ TRACE(("CASE_SU - scroll up\n"));
+ if ((count = param[0]) < 1)
+ count = 1;
+ xtermScroll(xw, count);
+ ResetState(sp);
+ break;
+
+ case CASE_SL: /* ISO 6429, non-DEC */
+ TRACE(("CASE_SL - scroll left\n"));
+ if ((count = param[0]) < 1)
+ count = 1;
+ xtermScrollLR(xw, count, True);
+ ResetState(sp);
+ break;
+
+ case CASE_SR: /* ISO 6429, non-DEC */
+ TRACE(("CASE_SR - scroll right\n"));
+ if ((count = param[0]) < 1)
+ count = 1;
+ xtermScrollLR(xw, count, False);
+ ResetState(sp);
+ break;
+
+ case CASE_DECDC:
+ TRACE(("CASE_DC - delete column\n"));
+ if (screen->vtXX_level >= 4
+ && IsLeftRightMode(xw)) {
+ if ((count = param[0]) < 1)
+ count = 1;
+ xtermColScroll(xw, count, True, screen->cur_col);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECIC:
+ TRACE(("CASE_IC - insert column\n"));
+ if (screen->vtXX_level >= 4
+ && IsLeftRightMode(xw)) {
+ if ((count = param[0]) < 1)
+ count = 1;
+ xtermColScroll(xw, count, False, screen->cur_col);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECBI:
+ TRACE(("CASE_BI - back index\n"));
+ if (screen->vtXX_level >= 4) {
+ xtermColIndex(xw, True);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECFI:
+ TRACE(("CASE_FI - forward index\n"));
+ if (screen->vtXX_level >= 4) {
+ xtermColIndex(xw, False);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_IND:
+ TRACE(("CASE_IND - index\n"));
+ xtermIndex(xw, 1);
+ do_xevents();
+ ResetState(sp);
+ break;
+
+ case CASE_CPL:
+ TRACE(("CASE_CPL - cursor prev line\n"));
+ CursorPrevLine(xw, param[0]);
+ ResetState(sp);
+ break;
+
+ case CASE_CNL:
+ TRACE(("CASE_CNL - cursor next line\n"));
+ CursorNextLine(xw, param[0]);
+ ResetState(sp);
+ break;
+
+ case CASE_NEL:
+ TRACE(("CASE_NEL\n"));
+ xtermIndex(xw, 1);
+ CarriageReturn(xw);
+ ResetState(sp);
+ break;
+
+ case CASE_HTS:
+ TRACE(("CASE_HTS - horizontal tab set\n"));
+ TabSet(xw->tabs, screen->cur_col);
+ ResetState(sp);
+ break;
+
+ case CASE_RI:
+ TRACE(("CASE_RI - reverse index\n"));
+ RevIndex(xw, 1);
+ ResetState(sp);
+ break;
+
+ case CASE_SS2:
+ TRACE(("CASE_SS2\n"));
+ screen->curss = 2;
+ ResetState(sp);
+ break;
+
+ case CASE_SS3:
+ TRACE(("CASE_SS3\n"));
+ screen->curss = 3;
+ ResetState(sp);
+ break;
+
+ case CASE_CSI_STATE:
+ /* enter csi state */
+ nparam = 1;
+ param[0] = DEFAULT;
+ sp->parsestate = csi_table;
+ break;
+
+ case CASE_ESC_SP_STATE:
+ /* esc space */
+ sp->parsestate = esc_sp_table;
+ break;
+
+ case CASE_CSI_EX_STATE:
+ /* csi exclamation */
+ sp->parsestate = csi_ex_table;
+ break;
+
+#if OPT_DEC_LOCATOR
+ case CASE_CSI_TICK_STATE:
+ /* csi tick (') */
+ sp->parsestate = csi_tick_table;
+ break;
+
+ case CASE_DECEFR:
+ TRACE(("CASE_DECEFR - Enable Filter Rectangle\n"));
+ if (screen->send_mouse_pos == DEC_LOCATOR) {
+ MotionOff(screen, xw);
+ if ((screen->loc_filter_top = param[0]) < 1)
+ screen->loc_filter_top = LOC_FILTER_POS;
+ if (nparam < 2 || (screen->loc_filter_left = param[1]) < 1)
+ screen->loc_filter_left = LOC_FILTER_POS;
+ if (nparam < 3 || (screen->loc_filter_bottom = param[2]) < 1)
+ screen->loc_filter_bottom = LOC_FILTER_POS;
+ if (nparam < 4 || (screen->loc_filter_right = param[3]) < 1)
+ screen->loc_filter_right = LOC_FILTER_POS;
+ InitLocatorFilter(xw);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECELR:
+ MotionOff(screen, xw);
+ if (param[0] <= 0 || param[0] > 2) {
+ screen->send_mouse_pos = MOUSE_OFF;
+ TRACE(("DECELR - Disable Locator Reports\n"));
+ } else {
+ TRACE(("DECELR - Enable Locator Reports\n"));
+ screen->send_mouse_pos = DEC_LOCATOR;
+ xtermShowPointer(xw, True);
+ if (param[0] == 2) {
+ screen->locator_reset = True;
+ } else {
+ screen->locator_reset = False;
+ }
+ if (nparam < 2 || param[1] != 1) {
+ screen->locator_pixels = False;
+ } else {
+ screen->locator_pixels = True;
+ }
+ screen->loc_filter = False;
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSLE:
+ TRACE(("DECSLE - Select Locator Events\n"));
+ for (count = 0; count < nparam; ++count) {
+ switch (param[count]) {
+ case DEFAULT:
+ case 0:
+ MotionOff(screen, xw);
+ screen->loc_filter = False;
+ screen->locator_events = 0;
+ break;
+ case 1:
+ screen->locator_events |= LOC_BTNS_DN;
+ break;
+ case 2:
+ UIntClr(screen->locator_events, LOC_BTNS_DN);
+ break;
+ case 3:
+ screen->locator_events |= LOC_BTNS_UP;
+ break;
+ case 4:
+ UIntClr(screen->locator_events, LOC_BTNS_UP);
+ break;
+ }
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECRQLP:
+ TRACE(("DECRQLP - Request Locator Position\n"));
+ if (param[0] < 2) {
+ /* Issue DECLRP Locator Position Report */
+ GetLocatorPosition(xw);
+ }
+ ResetState(sp);
+ break;
+#endif /* OPT_DEC_LOCATOR */
+
+#if OPT_DEC_RECTOPS
+ case CASE_CSI_DOLLAR_STATE:
+ TRACE(("CASE_CSI_DOLLAR_STATE\n"));
+ /* csi dollar ($) */
+ if (screen->vtXX_level >= 3)
+ sp->parsestate = csi_dollar_table;
+ else
+ sp->parsestate = eigtable;
+ break;
+
+ case CASE_CSI_STAR_STATE:
+ TRACE(("CASE_CSI_STAR_STATE\n"));
+ /* csi star (*) */
+ if (screen->vtXX_level >= 4)
+ sp->parsestate = csi_star_table;
+ else
+ sp->parsestate = eigtable;
+ break;
+
+ case CASE_DECRQCRA:
+ if (screen->vtXX_level >= 4) {
+ int checksum;
+
+ TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n"));
+ xtermCheckRect(xw, nparam, param, &checksum);
+ init_reply(ANSI_DCS);
+ count = 0;
+ reply.a_param[count++] = (ParmType) param[1]; /* PID */
+ reply.a_delim = "!~"; /* delimiter */
+ reply.a_radix[count] = 16;
+ reply.a_param[count++] = (ParmType) checksum;
+ reply.a_nparam = (ParmType) count;
+ unparseseq(xw, &reply);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECCRA:
+ if (screen->vtXX_level >= 4) {
+ TRACE(("CASE_DECCRA - Copy rectangular area\n"));
+ xtermParseRect(xw, nparam, param, &myRect);
+ ScrnCopyRectangle(xw, &myRect, nparam - 5, param + 5);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECERA:
+ if (screen->vtXX_level >= 4) {
+ TRACE(("CASE_DECERA - Erase rectangular area\n"));
+ xtermParseRect(xw, nparam, param, &myRect);
+ ScrnFillRectangle(xw, &myRect, ' ', 0, True);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECFRA:
+ if (screen->vtXX_level >= 4) {
+ TRACE(("CASE_DECFRA - Fill rectangular area\n"));
+ if (nparam > 0
+ && ((param[0] >= 32 && param[0] <= 126)
+ || (param[0] >= 160 && param[0] <= 255))) {
+ xtermParseRect(xw, nparam - 1, param + 1, &myRect);
+ ScrnFillRectangle(xw, &myRect, param[0], xw->flags, True);
+ }
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSERA:
+ if (screen->vtXX_level >= 4) {
+ TRACE(("CASE_DECSERA - Selective erase rectangular area\n"));
+ xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect);
+ ScrnWipeRectangle(xw, &myRect);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECSACE:
+ TRACE(("CASE_DECSACE - Select attribute change extent\n"));
+ screen->cur_decsace = param[0];
+ ResetState(sp);
+ break;
+
+ case CASE_DECCARA:
+ if (screen->vtXX_level >= 4) {
+ TRACE(("CASE_DECCARA - Change attributes in rectangular area\n"));
+ xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect);
+ ScrnMarkRectangle(xw, &myRect, False, nparam - 4, param + 4);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_DECRARA:
+ if (screen->vtXX_level >= 4) {
+ TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n"));
+ xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect);
+ ScrnMarkRectangle(xw, &myRect, True, nparam - 4, param + 4);
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_RQM:
+ TRACE(("CASE_RQM\n"));
+ do_rpm(xw, nparam, param);
+ ResetState(sp);
+ break;
+
+ case CASE_DECRQM:
+ TRACE(("CASE_DECRQM\n"));
+ do_decrpm(xw, nparam, param);
+ ResetState(sp);
+ break;
+
+ case CASE_CSI_DEC_DOLLAR_STATE:
+ TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n"));
+ /* csi ? dollar ($) */
+ sp->parsestate = csi_dec_dollar_table;
+ break;
+#else
+ case CASE_CSI_DOLLAR_STATE:
+ /* csi dollar ($) */
+ sp->parsestate = eigtable;
+ break;
+
+ case CASE_CSI_STAR_STATE:
+ /* csi dollar (*) */
+ sp->parsestate = eigtable;
+ break;
+
+ case CASE_CSI_DEC_DOLLAR_STATE:
+ /* csi ? dollar ($) */
+ sp->parsestate = eigtable;
+ break;
+#endif /* OPT_DEC_RECTOPS */
+
+ case CASE_S7C1T:
+ TRACE(("CASE_S7C1T\n"));
+ if (screen->vtXX_level >= 2) {
+ show_8bit_control(False);
+ ResetState(sp);
+ }
+ break;
+
+ case CASE_S8C1T:
+ TRACE(("CASE_S8C1T\n"));
+ if (screen->vtXX_level >= 2) {
+#if OPT_VT52_MODE
+ if (screen->vtXX_level <= 1)
+ break;
+#endif
+ show_8bit_control(True);
+ ResetState(sp);
+ }
+ break;
+
+ case CASE_OSC:
+ TRACE(("CASE_OSC: Operating System Command\n"));
+ sp->parsestate = sos_table;
+ sp->string_mode = ANSI_OSC;
+ break;
+
+ case CASE_RIS:
+ TRACE(("CASE_RIS\n"));
+ VTReset(xw, True, True);
+ ResetState(sp);
+ break;
+
+ case CASE_DECSTR:
+ TRACE(("CASE_DECSTR\n"));
+ VTReset(xw, False, False);
+ ResetState(sp);
+ break;
+
+ case CASE_REP:
+ TRACE(("CASE_REP\n"));
+ if (sp->lastchar >= 0 &&
+ sp->lastchar < 256 &&
+ sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) {
+ IChar repeated[2];
+ count = (param[0] < 1) ? 1 : param[0];
+ repeated[0] = (IChar) sp->lastchar;
+ while (count-- > 0) {
+ dotext(xw,
+ screen->gsets[(int) (screen->curgl)],
+ repeated, 1);
+ }
+ }
+ ResetState(sp);
+ break;
+
+ case CASE_LS2:
+ TRACE(("CASE_LS2\n"));
+ screen->curgl = 2;
+ ResetState(sp);
+ break;
+
+ case CASE_LS3:
+ TRACE(("CASE_LS3\n"));
+ screen->curgl = 3;
+ ResetState(sp);
+ break;
+
+ case CASE_LS3R:
+ TRACE(("CASE_LS3R\n"));
+ screen->curgr = 3;
+ ResetState(sp);
+ break;
+
+ case CASE_LS2R:
+ TRACE(("CASE_LS2R\n"));
+ screen->curgr = 2;
+ ResetState(sp);
+ break;
+
+ case CASE_LS1R:
+ TRACE(("CASE_LS1R\n"));
+ screen->curgr = 1;
+ ResetState(sp);
+ break;
+
+ case CASE_XTERM_SAVE:
+ savemodes(xw);
+ ResetState(sp);
+ break;
+
+ case CASE_XTERM_RESTORE:
+ restoremodes(xw);
+ ResetState(sp);
+ break;
+
+ case CASE_XTERM_WINOPS:
+ TRACE(("CASE_XTERM_WINOPS\n"));
+ window_ops(xw);
+ ResetState(sp);
+ break;
+#if OPT_WIDE_CHARS
+ case CASE_ESC_PERCENT:
+ sp->parsestate = esc_pct_table;
+ break;
+
+ case CASE_UTF8:
+ /* If we did not set UTF-8 mode from resource or the
+ * command-line, allow it to be enabled/disabled by
+ * control sequence.
+ */
+ if (screen->wide_chars
+ && screen->utf8_mode != uAlways) {
+ if (!screen->wide_chars) {
+ WriteNow();
+ ChangeToWide(xw);
+ }
+ switchPtyData(screen, c == 'G');
+ TRACE(("UTF8 mode %s\n",
+ BtoS(screen->utf8_mode)));
+ } else {
+ TRACE(("UTF8 mode NOT turned %s (%s)\n",
+ BtoS(c == 'G'),
+ (screen->utf8_mode == uAlways)
+ ? "UTF-8 mode set from command-line"
+ : "wideChars resource was not set"));
+ }
+ ResetState(sp);
+ break;
+#endif
+#if OPT_MOD_FKEYS
+ case CASE_SET_MOD_FKEYS:
+ TRACE(("CASE_SET_MOD_FKEYS\n"));
+ if (nparam >= 1) {
+ set_mod_fkeys(xw, param[0], nparam > 1 ? param[1] : DEFAULT, True);
+ } else {
+ for (row = 1; row <= 5; ++row)
+ set_mod_fkeys(xw, row, DEFAULT, True);
+ }
+ break;
+ case CASE_SET_MOD_FKEYS0:
+ TRACE(("CASE_SET_MOD_FKEYS0\n"));
+ if (nparam >= 1 && param[0] != DEFAULT) {
+ set_mod_fkeys(xw, param[0], -1, False);
+ } else {
+ xw->keyboard.modify_now.function_keys = -1;
+ }
+ break;
+#endif
+ case CASE_HIDE_POINTER:
+ TRACE(("CASE_HIDE_POINTER\n"));
+ if (nparam >= 1 && param[0] != DEFAULT) {
+ screen->pointer_mode = param[0];
+ } else {
+ screen->pointer_mode = DEF_POINTER_MODE;
+ }
+ break;
+
+ case CASE_SM_TITLE:
+ TRACE(("CASE_SM_TITLE\n"));
+ if (nparam >= 1) {
+ int n;
+ for (n = 0; n < nparam; ++n) {
+ if (param[n] != DEFAULT)
+ screen->title_modes |= (1 << param[n]);
+ }
+ } else {
+ screen->title_modes = DEF_TITLE_MODES;
+ }
+ TRACE(("...title_modes %#x\n", screen->title_modes));
+ break;
+
+ case CASE_RM_TITLE:
+ TRACE(("CASE_RM_TITLE\n"));
+ if (nparam >= 1) {
+ int n;
+ for (n = 0; n < nparam; ++n) {
+ if (param[n] != DEFAULT)
+ screen->title_modes &= ~(1 << param[n]);
+ }
+ } else {
+ screen->title_modes = DEF_TITLE_MODES;
+ }
+ TRACE(("...title_modes %#x\n", screen->title_modes));
+ break;
+
+ case CASE_CSI_IGNORE:
+ sp->parsestate = cigtable;
+ break;
+
+ case CASE_DECSWBV:
+ TRACE(("CASE_DECSWBV\n"));
+ switch ((nparam >= 1) ? param[0] : DEFAULT) {
+ case 2:
+ case 3:
+ case 4:
+ screen->warningVolume = bvLow;
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ screen->warningVolume = bvHigh;
+ break;
+ default:
+ screen->warningVolume = bvOff;
+ break;
+ }
+ TRACE(("...warningVolume %d\n", screen->warningVolume));
+ ResetState(sp);
+ break;
+
+ case CASE_DECSMBV:
+ TRACE(("CASE_DECSMBV\n"));
+ switch ((nparam >= 1) ? param[0] : DEFAULT) {
+ case 2:
+ case 3:
+ case 4:
+ screen->marginVolume = bvLow;
+ break;
+ case 0:
+ case DEFAULT:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ screen->marginVolume = bvHigh;
+ break;
+ default:
+ screen->marginVolume = bvOff;
+ break;
+ }
+ TRACE(("...marginVolume %d\n", screen->marginVolume));
+ ResetState(sp);
+ break;
+ }
+ if (sp->parsestate == sp->groundtable)
+ sp->lastchar = thischar;
+ } while (0);
+
+#if OPT_WIDE_CHARS
+ screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse)
+ && (sp->parsestate != sos_table));
+#endif
+
+ return True;
+}
+
+static void
+VTparse(XtermWidget xw)
+{
+ /* We longjmp back to this point in VTReset() */
+ (void) setjmp(vtjmpbuf);
+ init_parser(xw, &myState);
+
+ do {
+ } while (doparsing(xw, doinput(), &myState));
+}
+
+static Char *v_buffer; /* pointer to physical buffer */
+static Char *v_bufstr = NULL; /* beginning of area to write */
+static Char *v_bufptr; /* end of area to write */
+static Char *v_bufend; /* end of physical buffer */
+
+/* Write data to the pty as typed by the user, pasted with the mouse,
+ or generated by us in response to a query ESC sequence. */
+
+void
+v_write(int f, const Char * data, unsigned len)
+{
+ int riten;
+
+ TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len)));
+ if (v_bufstr == NULL && len > 0) {
+ v_buffer = (Char *) XtMalloc((Cardinal) len);
+ v_bufstr = v_buffer;
+ v_bufptr = v_buffer;
+ v_bufend = v_buffer + len;
+ }
+#ifdef DEBUG
+ if (debug) {
+ fprintf(stderr, "v_write called with %d bytes (%d left over)",
+ len, v_bufptr - v_bufstr);
+ if (len > 1 && len < 10)
+ fprintf(stderr, " \"%.*s\"", len, (const char *) data);
+ fprintf(stderr, "\n");
+ }
+#endif
+
+#ifdef VMS
+ if ((1 << f) != pty_mask) {
+ tt_write((const char *) data, len);
+ return;
+ }
+#else /* VMS */
+ if (!FD_ISSET(f, &pty_mask)) {
+ IGNORE_RC(write(f, (const char *) data, (size_t) len));
+ return;
+ }
+#endif /* VMS */
+
+ /*
+ * Append to the block we already have.
+ * Always doing this simplifies the code, and
+ * isn't too bad, either. If this is a short
+ * block, it isn't too expensive, and if this is
+ * a long block, we won't be able to write it all
+ * anyway.
+ */
+
+ if (len > 0) {
+#if OPT_DABBREV
+ TScreenOf(term)->dabbrev_working = False; /* break dabbrev sequence */
+#endif
+ if (v_bufend < v_bufptr + len) { /* we've run out of room */
+ if (v_bufstr != v_buffer) {
+ /* there is unused space, move everything down */
+ /* possibly overlapping memmove here */
+#ifdef DEBUG
+ if (debug)
+ fprintf(stderr, "moving data down %d\n",
+ v_bufstr - v_buffer);
+#endif
+ memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr));
+ v_bufptr -= v_bufstr - v_buffer;
+ v_bufstr = v_buffer;
+ }
+ if (v_bufend < v_bufptr + len) {
+ /* still won't fit: get more space */
+ /* Don't use XtRealloc because an error is not fatal. */
+ unsigned size = (unsigned) (v_bufptr - v_buffer);
+ v_buffer = TypeRealloc(Char, size + len, v_buffer);
+ if (v_buffer) {
+#ifdef DEBUG
+ if (debug)
+ fprintf(stderr, "expanded buffer to %d\n",
+ size + len);
+#endif
+ v_bufstr = v_buffer;
+ v_bufptr = v_buffer + size;
+ v_bufend = v_bufptr + len;
+ } else {
+ /* no memory: ignore entire write request */
+ xtermWarning("cannot allocate buffer space\n");
+ v_buffer = v_bufstr; /* restore clobbered pointer */
+ }
+ }
+ }
+ if (v_bufend >= v_bufptr + len) {
+ /* new stuff will fit */
+ memmove(v_bufptr, data, (size_t) len);
+ v_bufptr += len;
+ }
+ }
+
+ /*
+ * Write out as much of the buffer as we can.
+ * Be careful not to overflow the pty's input silo.
+ * We are conservative here and only write
+ * a small amount at a time.
+ *
+ * If we can't push all the data into the pty yet, we expect write
+ * to return a non-negative number less than the length requested
+ * (if some data written) or -1 and set errno to EAGAIN,
+ * EWOULDBLOCK, or EINTR (if no data written).
+ *
+ * (Not all systems do this, sigh, so the code is actually
+ * a little more forgiving.)
+ */
+
+#define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */
+
+ if (v_bufptr > v_bufstr) {
+#ifdef VMS
+ riten = tt_write(v_bufstr,
+ ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE)
+ ? v_bufptr - v_bufstr
+ : VMS_TERM_BUFFER_SIZE));
+ if (riten == 0)
+ return (riten);
+#else /* VMS */
+ riten = (int) write(f, v_bufstr,
+ (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE)
+ ? v_bufptr - v_bufstr
+ : MAX_PTY_WRITE));
+ if (riten < 0)
+#endif /* VMS */
+ {
+#ifdef DEBUG
+ if (debug)
+ perror("write");
+#endif
+ riten = 0;
+ }
+#ifdef DEBUG
+ if (debug)
+ fprintf(stderr, "write called with %d, wrote %d\n",
+ v_bufptr - v_bufstr <= MAX_PTY_WRITE ?
+ v_bufptr - v_bufstr : MAX_PTY_WRITE,
+ riten);
+#endif
+ v_bufstr += riten;
+ if (v_bufstr >= v_bufptr) /* we wrote it all */
+ v_bufstr = v_bufptr = v_buffer;
+ }
+
+ /*
+ * If we have lots of unused memory allocated, return it
+ */
+ if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */
+ /* save pointers across realloc */
+ int start = (int) (v_bufstr - v_buffer);
+ int size = (int) (v_bufptr - v_buffer);
+ unsigned allocsize = (unsigned) (size ? size : 1);
+
+ v_buffer = TypeRealloc(Char, allocsize, v_buffer);
+ if (v_buffer) {
+ v_bufstr = v_buffer + start;
+ v_bufptr = v_buffer + size;
+ v_bufend = v_buffer + allocsize;
+#ifdef DEBUG
+ if (debug)
+ fprintf(stderr, "shrunk buffer to %d\n", allocsize);
+#endif
+ } else {
+ /* should we print a warning if couldn't return memory? */
+ v_buffer = v_bufstr - start; /* restore clobbered pointer */
+ }
+ }
+}
+
+static void
+updateCursor(TScreen * screen)
+{
+ if (screen->cursor_set != screen->cursor_state) {
+ if (screen->cursor_set)
+ ShowCursor();
+ else
+ HideCursor();
+ }
+}
+
+#if OPT_BLINK_CURS || OPT_BLINK_TEXT
+static void
+reallyStopBlinking(TScreen * screen)
+{
+ if (screen->cursor_state == BLINKED_OFF) {
+ /* force cursor to display if it is enabled */
+ screen->cursor_state = !screen->cursor_set;
+ updateCursor(screen);
+ xevents();
+ }
+}
+#endif
+
+#ifdef VMS
+#define ptymask() (v_bufptr > v_bufstr ? pty_mask : 0)
+
+static void
+in_put(XtermWidget xw)
+{
+ static PtySelect select_mask;
+ static PtySelect write_mask;
+ int update = VTbuffer->update;
+ int size;
+
+ int status;
+ Dimension replyWidth, replyHeight;
+ XtGeometryResult stat;
+
+ TScreen *screen = TScreenOf(xw);
+ char *cp;
+ int i;
+
+ select_mask = pty_mask; /* force initial read */
+ for (;;) {
+
+ /* if the terminal changed size, resize the widget */
+ if (tt_changed) {
+ tt_changed = False;
+
+ stat = REQ_RESIZE((Widget) xw,
+ ((Dimension) FontWidth(screen)
+ * (tt_width)
+ + 2 * screen->border
+ + screen->fullVwin.sb_info.width),
+ ((Dimension) FontHeight(screen)
+ * (tt_length)
+ + 2 * screen->border),
+ &replyWidth, &replyHeight);
+
+ if (stat == XtGeometryYes || stat == XtGeometryDone) {
+ xw->core.width = replyWidth;
+ xw->core.height = replyHeight;
+
+ ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
+ }
+ repairSizeHints();
+ }
+
+ if (screen->eventMode == NORMAL
+ && readPtyData(xw, &select_mask, VTbuffer)) {
+ if (screen->scrollWidget
+ && screen->scrollttyoutput
+ && screen->topline < 0)
+ /* Scroll to bottom */
+ WindowScroll(xw, 0, False);
+ break;
+ }
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ if (screen->cursor_set && CursorMoved(screen)) {
+ if (screen->cursor_state)
+ HideCursor();
+ ShowCursor();
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+ PreeditPosition(xw);
+#endif
+ } else {
+ updateCursor(screen);
+ }
+
+ if (QLength(screen->display)) {
+ select_mask = X_mask;
+ } else {
+ write_mask = ptymask();
+ XFlush(screen->display);
+ select_mask = Select_mask;
+ if (screen->eventMode != NORMAL)
+ select_mask = X_mask;
+ }
+ if (write_mask & ptymask()) {
+ v_write(screen->respond, 0, 0); /* flush buffer */
+ }
+
+ if (select_mask & X_mask) {
+ xevents();
+ if (VTbuffer->update != update)
+ break;
+ }
+ }
+}
+#else /* VMS */
+
+static void
+in_put(XtermWidget xw)
+{
+ static PtySelect select_mask;
+ static PtySelect write_mask;
+
+ TScreen *screen = TScreenOf(xw);
+ int i, time_select;
+ int size;
+ int update = VTbuffer->update;
+
+ static struct timeval select_timeout;
+
+#if OPT_BLINK_CURS
+ /*
+ * Compute the timeout for the blinking cursor to be much smaller than
+ * the "on" or "off" interval.
+ */
+ int tick = ((screen->blink_on < screen->blink_off)
+ ? screen->blink_on
+ : screen->blink_off);
+ tick *= (1000 / 8); /* 1000 for msec/usec, 8 for "much" smaller */
+ if (tick < 1)
+ tick = 1;
+#endif
+
+ for (;;) {
+ if (screen->eventMode == NORMAL
+ && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) {
+ if (screen->scrollWidget
+ && screen->scrollttyoutput
+ && screen->topline < 0)
+ WindowScroll(xw, 0, False); /* Scroll to bottom */
+ /* stop speed reading at some point to look for X stuff */
+ TRACE(("VTbuffer uses %ld/%d\n",
+ (long) (VTbuffer->last - VTbuffer->buffer),
+ BUF_SIZE));
+ if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) {
+ FD_CLR(screen->respond, &select_mask);
+ break;
+ }
+#if defined(HAVE_SCHED_YIELD)
+ /*
+ * If we've read a full (small/fragment) buffer, let the operating
+ * system have a turn, and we'll resume reading until we've either
+ * read only a fragment of the buffer, or we've filled the large
+ * buffer (see above). Doing this helps keep up with large bursts
+ * of output.
+ */
+ if (size == FRG_SIZE) {
+ select_timeout.tv_sec = 0;
+ i = Select(max_plus1, &select_mask, &write_mask, 0,
+ &select_timeout);
+ if (i > 0) {
+ sched_yield();
+ } else
+ break;
+ } else {
+ break;
+ }
+#else
+ (void) size; /* unused in this branch */
+ break;
+#endif
+ }
+ /* update the screen */
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ if (screen->cursor_set && CursorMoved(screen)) {
+ if (screen->cursor_state)
+ HideCursor();
+ ShowCursor();
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+ PreeditPosition(xw);
+#endif
+ } else {
+ updateCursor(screen);
+ }
+
+ XFlush(screen->display); /* always flush writes before waiting */
+
+ /* Update the masks and, unless X events are already in the queue,
+ wait for I/O to be possible. */
+ XFD_COPYSET(&Select_mask, &select_mask);
+ /* in selection mode xterm does not read pty */
+ if (screen->eventMode != NORMAL)
+ FD_CLR(screen->respond, &select_mask);
+
+ if (v_bufptr > v_bufstr) {
+ XFD_COPYSET(&pty_mask, &write_mask);
+ } else
+ FD_ZERO(&write_mask);
+ select_timeout.tv_sec = 0;
+ time_select = 0;
+
+ /*
+ * if there's either an XEvent or an XtTimeout pending, just take
+ * a quick peek, i.e. timeout from the select() immediately. If
+ * there's nothing pending, let select() block a little while, but
+ * for a shorter interval than the arrow-style scrollbar timeout.
+ * The blocking is optional, because it tends to increase the load
+ * on the host.
+ */
+ if (xtermAppPending()) {
+ select_timeout.tv_usec = 0;
+ time_select = 1;
+ } else if (screen->awaitInput) {
+ select_timeout.tv_usec = 50000;
+ time_select = 1;
+#if OPT_BLINK_CURS
+ } else if ((screen->blink_timer != 0 &&
+ ((screen->select & FOCUS) || screen->always_highlight)) ||
+ (screen->cursor_state == BLINKED_OFF)) {
+ select_timeout.tv_usec = tick;
+ while (select_timeout.tv_usec > 1000000) {
+ select_timeout.tv_usec -= 1000000;
+ select_timeout.tv_sec++;
+ }
+ time_select = 1;
+#endif
+#if OPT_SESSION_MGT
+ } else if (resource.sessionMgt) {
+ if (ice_fd >= 0)
+ FD_SET(ice_fd, &select_mask);
+#endif
+ }
+ if (need_cleanup)
+ Cleanup(0);
+ i = Select(max_plus1, &select_mask, &write_mask, 0,
+ (time_select ? &select_timeout : 0));
+ if (i < 0) {
+ if (errno != EINTR)
+ SysError(ERROR_SELECT);
+ continue;
+ }
+
+ /* if there is room to write more data to the pty, go write more */
+ if (FD_ISSET(screen->respond, &write_mask)) {
+ v_write(screen->respond, (Char *) 0, 0); /* flush buffer */
+ }
+
+ /* if there are X events already in our queue, it
+ counts as being readable */
+ if (xtermAppPending() ||
+ FD_ISSET(ConnectionNumber(screen->display), &select_mask)) {
+ xevents();
+ if (VTbuffer->update != update) /* HandleInterpret */
+ break;
+ }
+
+ }
+}
+#endif /* VMS */
+
+static IChar
+doinput(void)
+{
+ TScreen *screen = TScreenOf(term);
+
+ while (!morePtyData(screen, VTbuffer))
+ in_put(term);
+ return nextPtyData(screen, VTbuffer);
+}
+
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+/*
+ * For OverTheSpot, client has to inform the position for XIM preedit.
+ */
+static void
+PreeditPosition(XtermWidget xw)
+{
+ TInput *input = lookupTInput(xw, (Widget) xw);
+ TScreen *screen = TScreenOf(xw);
+ LineData *ld;
+ XPoint spot;
+ XVaNestedList list;
+
+ if (input && input->xic
+ && (ld = getLineData(screen, screen->cur_row)) != 0) {
+ spot.x = (short) LineCursorX(screen, ld, screen->cur_col);
+ spot.y = (short) (CursorY(screen, screen->cur_row) + xw->misc.xim_fs_ascent);
+ list = XVaCreateNestedList(0,
+ XNSpotLocation, &spot,
+ XNForeground, T_COLOR(screen, TEXT_FG),
+ XNBackground, T_COLOR(screen, TEXT_BG),
+ (void *) 0);
+ XSetICValues(input->xic, XNPreeditAttributes, list, (void *) 0);
+ XFree(list);
+ }
+}
+#endif
+
+static void
+WrapLine(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ LineData *ld = getLineData(screen, screen->cur_row);
+
+ if (ld != 0) {
+ /* mark that we had to wrap this line */
+ LineSetFlag(ld, LINEWRAPPED);
+ if (screen->show_wrap_marks) {
+ ShowWrapMarks(xw, screen->cur_row, ld);
+ }
+ xtermAutoPrint(xw, '\n');
+ xtermIndex(xw, 1);
+ set_cur_col(screen, ScrnLeftMargin(xw));
+ }
+}
+
+/*
+ * process a string of characters according to the character set indicated
+ * by charset. worry about end of line conditions (wraparound if selected).
+ */
+void
+dotext(XtermWidget xw,
+ int charset,
+ IChar * buf, /* start of characters to process */
+ Cardinal len) /* end */
+{
+ TScreen *screen = TScreenOf(xw);
+#if OPT_WIDE_CHARS
+ Cardinal chars_chomped = 1;
+ int next_col = screen->cur_col;
+#else
+ int next_col, last_col, this_col; /* must be signed */
+#endif
+ Cardinal offset;
+ int right = ScrnRightMargin(xw);
+
+ /*
+ * It is possible to use CUP, etc., to move outside margins. In that
+ * case, the right-margin is ineffective.
+ */
+ if (screen->cur_col > right) {
+ right = screen->max_col;
+ }
+#if OPT_WIDE_CHARS
+ /* don't translate if we use UTF-8, and are not handling legacy support
+ * for line-drawing characters.
+ */
+ if ((screen->utf8_mode == uFalse)
+ || (screen->vt100_graphics))
+#endif
+ if (!xtermCharSetOut(xw, buf, buf + len, charset))
+ return;
+
+ if_OPT_XMC_GLITCH(screen, {
+ Cardinal n;
+ if (charset != '?') {
+ for (n = 0; n < len; n++) {
+ if (buf[n] == XMC_GLITCH)
+ buf[n] = XMC_GLITCH + 1;
+ }
+ }
+ });
+
+#if OPT_WIDE_CHARS
+ for (offset = 0;
+ offset < len && (chars_chomped > 0 || screen->do_wrap);
+ offset += chars_chomped) {
+ int width_available = right + 1 - screen->cur_col;
+ int width_here = 0;
+ Boolean need_wrap = False;
+ int last_chomp = 0;
+ chars_chomped = 0;
+
+ if (screen->do_wrap) {
+ screen->do_wrap = False;
+ if ((xw->flags & WRAPAROUND)) {
+ WrapLine(xw);
+ width_available = right + 1 - screen->cur_col;
+ next_col = screen->cur_col;
+ }
+ }
+
+ /*
+ * This can happen with left/right margins...
+ */
+ if (width_available <= 0)
+ break;
+
+ while (width_here <= width_available && chars_chomped < (len - offset)) {
+ if (!screen->utf8_mode
+ || (screen->vt100_graphics && charset == '0'))
+ last_chomp = 1;
+ else
+ last_chomp = my_wcwidth((int) buf[chars_chomped + offset]);
+ width_here += last_chomp;
+ chars_chomped++;
+ }
+
+ if (width_here > width_available) {
+ if (last_chomp > right + 1)
+ break; /* give up - it is too big */
+ if (chars_chomped-- == 0) {
+ /* This can happen with left/right margins... */
+ break;
+ }
+ width_here -= last_chomp;
+ if (chars_chomped > 0) {
+ need_wrap = True;
+ }
+ } else if (width_here == width_available) {
+ need_wrap = True;
+ } else if (chars_chomped != (len - offset)) {
+ need_wrap = True;
+ }
+
+ /*
+ * Split the wide characters back into separate arrays of 8-bit
+ * characters so we can use the existing interface.
+ *
+ * FIXME: If we rewrote this interface, it would involve
+ * rewriting all of the memory-management for the screen
+ * buffers (perhaps this is simpler).
+ */
+ if (chars_chomped != 0 && next_col <= screen->max_col) {
+ WriteText(xw, buf + offset, chars_chomped);
+ }
+ next_col += width_here;
+ screen->do_wrap = need_wrap;
+ }
+
+ /*
+ * Remember that we wrote something to the screen, for use as a base of
+ * combining characters. The logic above may have called cursor-forward
+ * or carriage-return operations which resets this flag, so we set it at
+ * the very end.
+ */
+ screen->char_was_written = True;
+#else /* ! OPT_WIDE_CHARS */
+
+ for (offset = 0; offset < len; offset += (Cardinal) this_col) {
+#if OPT_DEC_CHRSET
+ LineData *ld = getLineData(screen, screen->cur_row);
+#endif
+
+ last_col = LineMaxCol(screen, ld);
+ if (last_col > (right + 1))
+ last_col = right + 1;
+ this_col = last_col - screen->cur_col + 1;
+ if (this_col <= 1) {
+ if (screen->do_wrap) {
+ screen->do_wrap = False;
+ if ((xw->flags & WRAPAROUND)) {
+ WrapLine(xw);
+ }
+ }
+ this_col = 1;
+ }
+ if (offset + (Cardinal) this_col > len) {
+ this_col = (int) (len - offset);
+ }
+ next_col = screen->cur_col + this_col;
+
+ WriteText(xw, buf + offset, (unsigned) this_col);
+
+ /*
+ * The call to WriteText updates screen->cur_col.
+ * If screen->cur_col is less than next_col, we must have
+ * hit the right margin - so set the do_wrap flag.
+ */
+ screen->do_wrap = (Boolean) (screen->cur_col < next_col);
+ }
+
+#endif /* OPT_WIDE_CHARS */
+}
+
+#if OPT_WIDE_CHARS
+unsigned
+visual_width(IChar * str, Cardinal len)
+{
+ /* returns the visual width of a string (doublewide characters count
+ as 2, normalwide characters count as 1) */
+ unsigned my_len = 0;
+ while (len) {
+ int ch = (int) *str++;
+ if (isWide(ch))
+ my_len += 2;
+ else
+ my_len++;
+ len--;
+ }
+ return my_len;
+}
+#endif
+
+#if HANDLE_STRUCT_NOTIFY
+/* Flag icon name with "***" on window output when iconified.
+ */
+static void
+HandleStructNotify(Widget w GCC_UNUSED,
+ XtPointer closure GCC_UNUSED,
+ XEvent * event,
+ Boolean * cont GCC_UNUSED)
+{
+ XtermWidget xw = term;
+
+ switch (event->type) {
+ case MapNotify:
+ TRACE(("HandleStructNotify(MapNotify)\n"));
+ resetZIconBeep(xw);
+ mapstate = !IsUnmapped;
+ break;
+ case UnmapNotify:
+ TRACE(("HandleStructNotify(UnmapNotify)\n"));
+ mapstate = IsUnmapped;
+ break;
+ case ConfigureNotify:
+ if (event->xconfigure.window == XtWindow(toplevel)) {
+#if !OPT_TOOLBAR
+ int height, width;
+
+ height = event->xconfigure.height;
+ width = event->xconfigure.width;
+#endif
+ TRACE(("HandleStructNotify(ConfigureNotify) %d,%d %dx%d\n",
+ event->xconfigure.y, event->xconfigure.x,
+ event->xconfigure.height, event->xconfigure.width));
+
+#if OPT_TOOLBAR
+ /*
+ * The notification is for the top-level widget, but we care about
+ * vt100 (ignore the tek4014 window).
+ */
+ if (TScreenOf(xw)->Vshow) {
+ VTwin *Vwin = WhichVWin(TScreenOf(xw));
+ TbInfo *info = &(Vwin->tb_info);
+ TbInfo save = *info;
+
+ if (info->menu_bar) {
+ XtVaGetValues(info->menu_bar,
+ XtNheight, &info->menu_height,
+ XtNborderWidth, &info->menu_border,
+ (XtPointer) 0);
+
+ if (save.menu_height != info->menu_height
+ || save.menu_border != info->menu_border) {
+
+ TRACE(("...menu_height %d\n", info->menu_height));
+ TRACE(("...menu_border %d\n", info->menu_border));
+ TRACE(("...had height %d, border %d\n",
+ save.menu_height,
+ save.menu_border));
+
+ /*
+ * Window manager still may be using the old values.
+ * Try to fool it.
+ */
+ REQ_RESIZE((Widget) xw,
+ TScreenOf(xw)->fullVwin.fullwidth,
+ (Dimension) (info->menu_height
+ - save.menu_height
+ + TScreenOf(xw)->fullVwin.fullheight),
+ NULL, NULL);
+ repairSizeHints();
+ }
+ }
+ }
+#else
+ if (height != xw->hints.height || width != xw->hints.width)
+ RequestResize(xw, height, width, False);
+#endif /* OPT_TOOLBAR */
+ }
+ break;
+ case ReparentNotify:
+ TRACE(("HandleStructNotify(ReparentNotify)\n"));
+ break;
+ default:
+ TRACE(("HandleStructNotify(event %s)\n",
+ visibleEventType(event->type)));
+ break;
+ }
+}
+#endif /* HANDLE_STRUCT_NOTIFY */
+
+#if OPT_BLINK_CURS
+static void
+SetCursorBlink(TScreen * screen, Bool enable)
+{
+ screen->cursor_blink = (Boolean) enable;
+ if (DoStartBlinking(screen)) {
+ StartBlinking(screen);
+ } else {
+ /* EMPTY */
+#if OPT_BLINK_TEXT
+ reallyStopBlinking(screen);
+#else
+ StopBlinking(screen);
+#endif
+ }
+ update_cursorblink();
+}
+
+void
+ToggleCursorBlink(TScreen * screen)
+{
+ SetCursorBlink(screen, (Bool) (!(screen->cursor_blink)));
+}
+#endif
+
+/*
+ * process ANSI modes set, reset
+ */
+static void
+ansi_modes(XtermWidget xw, BitFunc func)
+{
+ int i;
+
+ for (i = 0; i < nparam; ++i) {
+ switch (param[i]) {
+ case 2: /* KAM (if set, keyboard locked */
+ (*func) (&xw->keyboard.flags, MODE_KAM);
+ break;
+
+ case 4: /* IRM */
+ (*func) (&xw->flags, INSERT);
+ break;
+
+ case 12: /* SRM (if set, local echo */
+ (*func) (&xw->keyboard.flags, MODE_SRM);
+ break;
+
+ case 20: /* LNM */
+ (*func) (&xw->flags, LINEFEED);
+ update_autolinefeed();
+ break;
+ }
+ }
+}
+
+#define IsSM() (func == bitset)
+
+#define set_bool_mode(flag) \
+ flag = (Boolean) IsSM()
+
+static void
+really_set_mousemode(XtermWidget xw,
+ Bool enabled,
+ XtermMouseModes mode)
+{
+ TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF;
+ if (TScreenOf(xw)->send_mouse_pos != MOUSE_OFF)
+ xtermShowPointer(xw, True);
+}
+
+#define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode)
+
+#if OPT_READLINE
+#define set_mouseflag(f) \
+ (IsSM() \
+ ? SCREEN_FLAG_set(screen, f) \
+ : SCREEN_FLAG_unset(screen, f))
+#endif
+
+/*
+ * Use this enumerated type to check consistency among dpmodes(), savemodes()
+ * and restoremodes().
+ */
+typedef enum {
+ srm_DECCKM = 1
+ ,srm_DECANM = 2
+ ,srm_DECCOLM = 3
+ ,srm_DECSCLM = 4
+ ,srm_DECSCNM = 5
+ ,srm_DECOM = 6
+ ,srm_DECAWM = 7
+ ,srm_DECARM = 8
+ ,srm_X10_MOUSE = SET_X10_MOUSE
+#if OPT_TOOLBAR
+ ,srm_RXVT_TOOLBAR = 10
+#endif
+#if OPT_BLINK_CURS
+ ,srm_ATT610_BLINK = 12
+#endif
+ ,srm_DECPFF = 18
+ ,srm_DECPEX = 19
+ ,srm_DECTCEM = 25
+ ,srm_RXVT_SCROLLBAR = 30
+#if OPT_SHIFT_FONTS
+ ,srm_RXVT_FONTSIZE = 35
+#endif
+#if OPT_TEK4014
+ ,srm_DECTEK = 38
+#endif
+ ,srm_132COLS = 40
+ ,srm_CURSES_HACK = 41
+ ,srm_DECNRCM = 42
+ ,srm_MARGIN_BELL = 44
+ ,srm_REVERSEWRAP = 45
+#ifdef ALLOWLOGGING
+ ,srm_ALLOWLOGGING = 46
+#endif
+ ,srm_OPT_ALTBUF_CURSOR = 1049
+ ,srm_OPT_ALTBUF = 1047
+ ,srm_ALTBUF = 47
+ ,srm_DECNKM = 66
+ ,srm_DECBKM = 67
+ ,srm_DECLRMM = 69
+ ,srm_DECNCSM = 95
+ ,srm_VT200_MOUSE = SET_VT200_MOUSE
+ ,srm_VT200_HIGHLIGHT_MOUSE = SET_VT200_HIGHLIGHT_MOUSE
+ ,srm_BTN_EVENT_MOUSE = SET_BTN_EVENT_MOUSE
+ ,srm_ANY_EVENT_MOUSE = SET_ANY_EVENT_MOUSE
+#if OPT_FOCUS_EVENT
+ ,srm_FOCUS_EVENT_MOUSE = SET_FOCUS_EVENT_MOUSE
+#endif
+ ,srm_EXT_MODE_MOUSE = SET_EXT_MODE_MOUSE
+ ,srm_SGR_EXT_MODE_MOUSE = SET_SGR_EXT_MODE_MOUSE
+ ,srm_URXVT_EXT_MODE_MOUSE = SET_URXVT_EXT_MODE_MOUSE
+ ,srm_RXVT_SCROLL_TTY_OUTPUT = 1010
+ ,srm_RXVT_SCROLL_TTY_KEYPRESS = 1011
+ ,srm_EIGHT_BIT_META = 1034
+#if OPT_NUM_LOCK
+ ,srm_REAL_NUMLOCK = 1035
+ ,srm_META_SENDS_ESC = 1036
+#endif
+ ,srm_DELETE_IS_DEL = 1037
+#if OPT_NUM_LOCK
+ ,srm_ALT_SENDS_ESC = 1039
+#endif
+ ,srm_KEEP_SELECTION = 1040
+ ,srm_SELECT_TO_CLIPBOARD = 1041
+ ,srm_BELL_IS_URGENT = 1042
+ ,srm_POP_ON_BELL = 1043
+ ,srm_TITE_INHIBIT = 1048
+#if OPT_TCAP_FKEYS
+ ,srm_TCAP_FKEYS = 1050
+#endif
+#if OPT_SUN_FUNC_KEYS
+ ,srm_SUN_FKEYS = 1051
+#endif
+#if OPT_HP_FUNC_KEYS
+ ,srm_HP_FKEYS = 1052
+#endif
+#if OPT_SCO_FUNC_KEYS
+ ,srm_SCO_FKEYS = 1053
+#endif
+ ,srm_LEGACY_FKEYS = 1060
+#if OPT_SUNPC_KBD
+ ,srm_VT220_FKEYS = 1061
+#endif
+#if OPT_READLINE
+ ,srm_BUTTON1_MOVE_POINT = SET_BUTTON1_MOVE_POINT
+ ,srm_BUTTON2_MOVE_POINT = SET_BUTTON2_MOVE_POINT
+ ,srm_DBUTTON3_DELETE = SET_DBUTTON3_DELETE
+ ,srm_PASTE_IN_BRACKET = SET_PASTE_IN_BRACKET
+ ,srm_PASTE_QUOTE = SET_PASTE_QUOTE
+ ,srm_PASTE_LITERAL_NL = SET_PASTE_LITERAL_NL
+#endif /* OPT_READLINE */
+} DECSET_codes;
+
+/*
+ * process DEC private modes set, reset
+ */
+static void
+dpmodes(XtermWidget xw, BitFunc func)
+{
+ TScreen *screen = TScreenOf(xw);
+ int i, j;
+ unsigned myflags;
+
+ for (i = 0; i < nparam; ++i) {
+ TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", param[i]));
+ switch ((DECSET_codes) param[i]) {
+ case srm_DECCKM:
+ (*func) (&xw->keyboard.flags, MODE_DECCKM);
+ update_appcursor();
+ break;
+ case srm_DECANM: /* ANSI/VT52 mode */
+ if (IsSM()) { /* ANSI (VT100) */
+ /*
+ * Setting DECANM should have no effect, since this function
+ * cannot be reached from vt52 mode.
+ */
+ /* EMPTY */ ;
+ }
+#if OPT_VT52_MODE
+ else if (screen->terminal_id >= 100) { /* VT52 */
+ TRACE(("DECANM terminal_id %d, vtXX_level %d\n",
+ screen->terminal_id,
+ screen->vtXX_level));
+ screen->vtXX_level = 0;
+ screen->vt52_save_curgl = screen->curgl;
+ screen->vt52_save_curgr = screen->curgr;
+ screen->vt52_save_curss = screen->curss;
+ memmove(screen->vt52_save_gsets, screen->gsets, sizeof(screen->gsets));
+ resetCharsets(screen);
+ nparam = 0; /* ignore the remaining params, if any */
+ }
+#endif
+ break;
+ case srm_DECCOLM:
+ if (screen->c132) {
+ if (!(xw->flags & NOCLEAR_COLM))
+ ClearScreen(xw);
+ CursorSet(screen, 0, 0, xw->flags);
+ if ((j = IsSM()? 132 : 80) !=
+ ((xw->flags & IN132COLUMNS) ? 132 : 80) ||
+ j != MaxCols(screen))
+ RequestResize(xw, -1, j, True);
+ (*func) (&xw->flags, IN132COLUMNS);
+ if (xw->flags & IN132COLUMNS) {
+ UIntClr(xw->flags, LEFT_RIGHT);
+ reset_lr_margins(screen);
+ }
+ }
+ break;
+ case srm_DECSCLM: /* (slow scroll) */
+ if (IsSM()) {
+ screen->jumpscroll = 0;
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ } else
+ screen->jumpscroll = 1;
+ (*func) (&xw->flags, SMOOTHSCROLL);
+ update_jumpscroll();
+ break;
+ case srm_DECSCNM:
+ myflags = xw->flags;
+ (*func) (&xw->flags, REVERSE_VIDEO);
+ if ((xw->flags ^ myflags) & REVERSE_VIDEO)
+ ReverseVideo(xw);
+ /* update_reversevideo done in RevVid */
+ break;
+
+ case srm_DECOM:
+ (*func) (&xw->flags, ORIGIN);
+ CursorSet(screen, 0, 0, xw->flags);
+ break;
+
+ case srm_DECAWM:
+ (*func) (&xw->flags, WRAPAROUND);
+ update_autowrap();
+ break;
+ case srm_DECARM:
+ /* ignore autorepeat
+ * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only
+ * for the whole display - not limited to a given window.
+ */
+ break;
+ case srm_X10_MOUSE: /* MIT bogus sequence */
+ MotionOff(screen, xw);
+ set_mousemode(X10_MOUSE);
+ break;
+#if OPT_TOOLBAR
+ case srm_RXVT_TOOLBAR:
+ ShowToolbar(IsSM());
+ break;
+#endif
+#if OPT_BLINK_CURS
+ case srm_ATT610_BLINK: /* att610: Start/stop blinking cursor */
+ if (screen->cursor_blink_res) {
+ set_bool_mode(screen->cursor_blink_esc);
+ UpdateCursorBlink(screen);
+ }
+ break;
+#endif
+ case srm_DECPFF: /* print form feed */
+ set_bool_mode(PrinterOf(screen).printer_formfeed);
+ break;
+ case srm_DECPEX: /* print extent */
+ set_bool_mode(PrinterOf(screen).printer_extent);
+ break;
+ case srm_DECTCEM: /* Show/hide cursor (VT200) */
+ set_bool_mode(screen->cursor_set);
+ break;
+ case srm_RXVT_SCROLLBAR:
+ if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF))
+ ToggleScrollBar(xw);
+ break;
+#if OPT_SHIFT_FONTS
+ case srm_RXVT_FONTSIZE:
+ set_bool_mode(xw->misc.shift_fonts);
+ break;
+#endif
+#if OPT_TEK4014
+ case srm_DECTEK:
+ if (IsSM() && !(screen->inhibit & I_TEK)) {
+ FlushLog(xw);
+ TEK4014_ACTIVE(xw) = True;
+ }
+ break;
+#endif
+ case srm_132COLS: /* 132 column mode */
+ set_bool_mode(screen->c132);
+ update_allow132();
+ break;
+ case srm_CURSES_HACK:
+ set_bool_mode(screen->curses);
+ update_cursesemul();
+ break;
+ case srm_DECNRCM: /* national charset (VT220) */
+ (*func) (&xw->flags, NATIONAL);
+ break;
+ case srm_MARGIN_BELL: /* margin bell */
+ set_bool_mode(screen->marginbell);
+ if (!screen->marginbell)
+ screen->bellArmed = -1;
+ update_marginbell();
+ break;
+ case srm_REVERSEWRAP: /* reverse wraparound */
+ (*func) (&xw->flags, REVERSEWRAP);
+ update_reversewrap();
+ break;
+#ifdef ALLOWLOGGING
+ case srm_ALLOWLOGGING: /* logging */
+#ifdef ALLOWLOGFILEONOFF
+ /*
+ * if this feature is enabled, logging may be
+ * enabled and disabled via escape sequences.
+ */
+ if (IsSM())
+ StartLog(xw);
+ else
+ CloseLog(xw);
+#else
+ Bell(xw, XkbBI_Info, 0);
+ Bell(xw, XkbBI_Info, 0);
+#endif /* ALLOWLOGFILEONOFF */
+ break;
+#endif
+ case srm_OPT_ALTBUF_CURSOR: /* alternate buffer & cursor */
+ if (!xw->misc.titeInhibit) {
+ if (IsSM()) {
+ CursorSave(xw);
+ ToAlternate(xw);
+ ClearScreen(xw);
+ } else {
+ FromAlternate(xw);
+ CursorRestore(xw);
+ }
+ } else if (xw->misc.tiXtraScroll) {
+ if (IsSM()) {
+ xtermScroll(xw, screen->max_row);
+ }
+ }
+ break;
+ case srm_OPT_ALTBUF:
+ /* FALLTHRU */
+ case srm_ALTBUF: /* alternate buffer */
+ if (!xw->misc.titeInhibit) {
+ if (IsSM()) {
+ ToAlternate(xw);
+ } else {
+ if (screen->whichBuf
+ && (param[i] == 1047))
+ ClearScreen(xw);
+ FromAlternate(xw);
+ }
+ } else if (xw->misc.tiXtraScroll) {
+ if (IsSM()) {
+ xtermScroll(xw, screen->max_row);
+ }
+ }
+ break;
+ case srm_DECNKM:
+ (*func) (&xw->keyboard.flags, MODE_DECKPAM);
+ update_appkeypad();
+ break;
+ case srm_DECBKM:
+ /* back-arrow mapped to backspace or delete(D) */
+ (*func) (&xw->keyboard.flags, MODE_DECBKM);
+ TRACE(("DECSET DECBKM %s\n",
+ BtoS(xw->keyboard.flags & MODE_DECBKM)));
+ update_decbkm();
+ break;
+ case srm_DECLRMM:
+ if (screen->vtXX_level >= 4) { /* VT420 */
+ (*func) (&xw->flags, LEFT_RIGHT);
+ if (IsLeftRightMode(xw)) {
+ xterm_ResetDouble(xw);
+ } else {
+ reset_lr_margins(screen);
+ }
+ CursorSet(screen, 0, 0, xw->flags);
+ }
+ break;
+ case srm_DECNCSM:
+ if (screen->vtXX_level >= 5) { /* VT510 */
+ (*func) (&xw->flags, NOCLEAR_COLM);
+ }
+ break;
+ case srm_VT200_MOUSE: /* xterm bogus sequence */
+ MotionOff(screen, xw);
+ set_mousemode(VT200_MOUSE);
+ break;
+ case srm_VT200_HIGHLIGHT_MOUSE: /* xterm sequence w/hilite tracking */
+ MotionOff(screen, xw);
+ set_mousemode(VT200_HIGHLIGHT_MOUSE);
+ break;
+ case srm_BTN_EVENT_MOUSE:
+ MotionOff(screen, xw);
+ set_mousemode(BTN_EVENT_MOUSE);
+ break;
+ case srm_ANY_EVENT_MOUSE:
+ set_mousemode(ANY_EVENT_MOUSE);
+ if (screen->send_mouse_pos == MOUSE_OFF) {
+ MotionOff(screen, xw);
+ } else {
+ MotionOn(screen, xw);
+ }
+ break;
+#if OPT_FOCUS_EVENT
+ case srm_FOCUS_EVENT_MOUSE:
+ set_bool_mode(screen->send_focus_pos);
+ break;
+#endif
+ case srm_EXT_MODE_MOUSE:
+ /* FALLTHRU */
+ case srm_SGR_EXT_MODE_MOUSE:
+ /* FALLTHRU */
+ case srm_URXVT_EXT_MODE_MOUSE:
+ /*
+ * Rather than choose an arbitrary precedence among the coordinate
+ * modes, they are mutually exclusive. For consistency, a reset is
+ * only effective against the matching mode.
+ */
+ if (IsSM()) {
+ screen->extend_coords = param[i];
+ } else if (screen->extend_coords == param[i]) {
+ screen->extend_coords = 0;
+ }
+ break;
+ case srm_RXVT_SCROLL_TTY_OUTPUT:
+ set_bool_mode(screen->scrollttyoutput);
+ update_scrollttyoutput();
+ break;
+ case srm_RXVT_SCROLL_TTY_KEYPRESS:
+ set_bool_mode(screen->scrollkey);
+ update_scrollkey();
+ break;
+ case srm_EIGHT_BIT_META:
+ if (screen->eight_bit_meta != ebNever) {
+ set_bool_mode(screen->eight_bit_meta);
+ }
+ break;
+#if OPT_NUM_LOCK
+ case srm_REAL_NUMLOCK:
+ set_bool_mode(xw->misc.real_NumLock);
+ update_num_lock();
+ break;
+ case srm_META_SENDS_ESC:
+ set_bool_mode(screen->meta_sends_esc);
+ update_meta_esc();
+ break;
+#endif
+ case srm_DELETE_IS_DEL:
+ set_bool_mode(screen->delete_is_del);
+ update_delete_del();
+ break;
+#if OPT_NUM_LOCK
+ case srm_ALT_SENDS_ESC:
+ set_bool_mode(screen->alt_sends_esc);
+ update_alt_esc();
+ break;
+#endif
+ case srm_KEEP_SELECTION:
+ set_bool_mode(screen->keepSelection);
+ update_keepSelection();
+ break;
+ case srm_SELECT_TO_CLIPBOARD:
+ set_bool_mode(screen->selectToClipboard);
+ update_selectToClipboard();
+ break;
+ case srm_BELL_IS_URGENT:
+ set_bool_mode(screen->bellIsUrgent);
+ update_bellIsUrgent();
+ break;
+ case srm_POP_ON_BELL:
+ set_bool_mode(screen->poponbell);
+ update_poponbell();
+ break;
+ case srm_TITE_INHIBIT:
+ if (!xw->misc.titeInhibit) {
+ if (IsSM())
+ CursorSave(xw);
+ else
+ CursorRestore(xw);
+ }
+ break;
+#if OPT_TCAP_FKEYS
+ case srm_TCAP_FKEYS:
+ set_keyboard_type(xw, keyboardIsTermcap, IsSM());
+ break;
+#endif
+#if OPT_SUN_FUNC_KEYS
+ case srm_SUN_FKEYS:
+ set_keyboard_type(xw, keyboardIsSun, IsSM());
+ break;
+#endif
+#if OPT_HP_FUNC_KEYS
+ case srm_HP_FKEYS:
+ set_keyboard_type(xw, keyboardIsHP, IsSM());
+ break;
+#endif
+#if OPT_SCO_FUNC_KEYS
+ case srm_SCO_FKEYS:
+ set_keyboard_type(xw, keyboardIsSCO, IsSM());
+ break;
+#endif
+ case srm_LEGACY_FKEYS:
+ set_keyboard_type(xw, keyboardIsLegacy, IsSM());
+ break;
+#if OPT_SUNPC_KBD
+ case srm_VT220_FKEYS:
+ set_keyboard_type(xw, keyboardIsVT220, IsSM());
+ break;
+#endif
+#if OPT_READLINE
+ case srm_BUTTON1_MOVE_POINT:
+ set_mouseflag(click1_moves);
+ break;
+ case srm_BUTTON2_MOVE_POINT:
+ set_mouseflag(paste_moves);
+ break;
+ case srm_DBUTTON3_DELETE:
+ set_mouseflag(dclick3_deletes);
+ break;
+ case srm_PASTE_IN_BRACKET:
+ set_mouseflag(paste_brackets);
+ break;
+ case srm_PASTE_QUOTE:
+ set_mouseflag(paste_quotes);
+ break;
+ case srm_PASTE_LITERAL_NL:
+ set_mouseflag(paste_literal_nl);
+ break;
+#endif /* OPT_READLINE */
+ }
+ }
+}
+
+/*
+ * process xterm private modes save
+ */
+static void
+savemodes(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ int i;
+
+ for (i = 0; i < nparam; i++) {
+ TRACE(("savemodes %d\n", param[i]));
+ switch ((DECSET_codes) param[i]) {
+ case srm_DECCKM:
+ DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM);
+ break;
+ case srm_DECANM: /* ANSI/VT52 mode */
+ /* no effect */
+ break;
+ case srm_DECCOLM:
+ if (screen->c132)
+ DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS);
+ break;
+ case srm_DECSCLM: /* (slow scroll) */
+ DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL);
+ break;
+ case srm_DECSCNM:
+ DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO);
+ break;
+ case srm_DECOM:
+ DoSM(DP_DECOM, xw->flags & ORIGIN);
+ break;
+ case srm_DECAWM:
+ DoSM(DP_DECAWM, xw->flags & WRAPAROUND);
+ break;
+ case srm_DECARM:
+ /* ignore autorepeat */
+ break;
+ case srm_X10_MOUSE: /* mouse bogus sequence */
+ DoSM(DP_X_X10MSE, screen->send_mouse_pos);
+ break;
+#if OPT_TOOLBAR
+ case srm_RXVT_TOOLBAR:
+ DoSM(DP_TOOLBAR, resource.toolBar);
+ break;
+#endif
+#if OPT_BLINK_CURS
+ case srm_ATT610_BLINK: /* att610: Start/stop blinking cursor */
+ if (screen->cursor_blink_res) {
+ DoSM(DP_CRS_BLINK, screen->cursor_blink_esc);
+ }
+ break;
+#endif
+ case srm_DECPFF: /* print form feed */
+ DoSM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed);
+ break;
+ case srm_DECPEX: /* print extent */
+ DoSM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent);
+ break;
+ case srm_DECTCEM: /* Show/hide cursor (VT200) */
+ DoSM(DP_CRS_VISIBLE, screen->cursor_set);
+ break;
+ case srm_RXVT_SCROLLBAR:
+ DoSM(DP_RXVT_SCROLLBAR, (screen->fullVwin.sb_info.width != 0));
+ break;
+#if OPT_SHIFT_FONTS
+ case srm_RXVT_FONTSIZE:
+ DoSM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts);
+ break;
+#endif
+#if OPT_TEK4014
+ case srm_DECTEK:
+ DoSM(DP_DECTEK, TEK4014_ACTIVE(xw));
+ break;
+#endif
+ case srm_132COLS: /* 132 column mode */
+ DoSM(DP_X_DECCOLM, screen->c132);
+ break;
+ case srm_CURSES_HACK: /* curses hack */
+ DoSM(DP_X_MORE, screen->curses);
+ break;
+ case srm_DECNRCM: /* national charset (VT220) */
+ DoSM(DP_DECNRCM, xw->flags & NATIONAL);
+ break;
+ case srm_MARGIN_BELL: /* margin bell */
+ DoSM(DP_X_MARGIN, screen->marginbell);
+ break;
+ case srm_REVERSEWRAP: /* reverse wraparound */
+ DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP);
+ break;
+#ifdef ALLOWLOGGING
+ case srm_ALLOWLOGGING: /* logging */
+ DoSM(DP_X_LOGGING, screen->logging);
+ break;
+#endif
+ case srm_OPT_ALTBUF_CURSOR:
+ /* FALLTHRU */
+ case srm_OPT_ALTBUF:
+ /* FALLTHRU */
+ case srm_ALTBUF: /* alternate buffer */
+ DoSM(DP_X_ALTSCRN, screen->whichBuf);
+ break;
+ case srm_DECNKM:
+ DoSM(DP_DECKPAM, xw->keyboard.flags & MODE_DECKPAM);
+ break;
+ case srm_DECBKM:
+ DoSM(DP_DECBKM, xw->keyboard.flags & MODE_DECBKM);
+ break;
+ case srm_DECLRMM: /* left-right */
+ DoSM(DP_X_LRMM, LEFT_RIGHT);
+ break;
+ case srm_DECNCSM: /* noclear */
+ DoSM(DP_X_NCSM, NOCLEAR_COLM);
+ break;
+ case srm_VT200_MOUSE: /* mouse bogus sequence */
+ case srm_VT200_HIGHLIGHT_MOUSE:
+ case srm_BTN_EVENT_MOUSE:
+ case srm_ANY_EVENT_MOUSE:
+ DoSM(DP_X_MOUSE, screen->send_mouse_pos);
+ break;
+#if OPT_FOCUS_EVENT
+ case srm_FOCUS_EVENT_MOUSE:
+ DoSM(DP_X_FOCUS, screen->send_focus_pos);
+ break;
+#endif
+ case srm_EXT_MODE_MOUSE:
+ /* FALLTHRU */
+ case srm_SGR_EXT_MODE_MOUSE:
+ /* FALLTHRU */
+ case srm_URXVT_EXT_MODE_MOUSE:
+ DoSM(DP_X_EXT_MOUSE, screen->extend_coords);
+ break;
+ case srm_RXVT_SCROLL_TTY_OUTPUT:
+ DoSM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput);
+ break;
+ case srm_RXVT_SCROLL_TTY_KEYPRESS:
+ DoSM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey);
+ break;
+ case srm_EIGHT_BIT_META:
+ DoSM(DP_EIGHT_BIT_META, screen->eight_bit_meta);
+ break;
+#if OPT_NUM_LOCK
+ case srm_REAL_NUMLOCK:
+ DoSM(DP_REAL_NUMLOCK, xw->misc.real_NumLock);
+ break;
+ case srm_META_SENDS_ESC:
+ DoSM(DP_META_SENDS_ESC, screen->meta_sends_esc);
+ break;
+#endif
+ case srm_DELETE_IS_DEL:
+ DoSM(DP_DELETE_IS_DEL, screen->delete_is_del);
+ break;
+#if OPT_NUM_LOCK
+ case srm_ALT_SENDS_ESC:
+ DoSM(DP_ALT_SENDS_ESC, screen->alt_sends_esc);
+ break;
+#endif
+ case srm_KEEP_SELECTION:
+ DoSM(DP_KEEP_SELECTION, screen->keepSelection);
+ break;
+ case srm_SELECT_TO_CLIPBOARD:
+ DoSM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard);
+ break;
+ case srm_BELL_IS_URGENT:
+ DoSM(DP_BELL_IS_URGENT, screen->bellIsUrgent);
+ break;
+ case srm_POP_ON_BELL:
+ DoSM(DP_POP_ON_BELL, screen->poponbell);
+ break;
+#if OPT_TCAP_FKEYS
+ case srm_TCAP_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_SUN_FUNC_KEYS
+ case srm_SUN_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_HP_FUNC_KEYS
+ case srm_HP_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_SCO_FUNC_KEYS
+ case srm_SCO_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_SUNPC_KBD
+ case srm_VT220_FKEYS:
+ /* FALLTHRU */
+#endif
+ case srm_LEGACY_FKEYS:
+ DoSM(DP_KEYBOARD_TYPE, xw->keyboard.type);
+ break;
+ case srm_TITE_INHIBIT:
+ if (!xw->misc.titeInhibit) {
+ CursorSave(xw);
+ }
+ break;
+#if OPT_READLINE
+ case srm_BUTTON1_MOVE_POINT:
+ SCREEN_FLAG_save(screen, click1_moves);
+ break;
+ case srm_BUTTON2_MOVE_POINT:
+ SCREEN_FLAG_save(screen, paste_moves);
+ break;
+ case srm_DBUTTON3_DELETE:
+ SCREEN_FLAG_save(screen, dclick3_deletes);
+ break;
+ case srm_PASTE_IN_BRACKET:
+ SCREEN_FLAG_save(screen, paste_brackets);
+ break;
+ case srm_PASTE_QUOTE:
+ SCREEN_FLAG_save(screen, paste_quotes);
+ break;
+ case srm_PASTE_LITERAL_NL:
+ SCREEN_FLAG_save(screen, paste_literal_nl);
+ break;
+#endif /* OPT_READLINE */
+ }
+ }
+}
+
+/*
+ * process xterm private modes restore
+ */
+static void
+restoremodes(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ int i, j;
+
+ for (i = 0; i < nparam; i++) {
+ TRACE(("restoremodes %d\n", param[i]));
+ switch ((DECSET_codes) param[i]) {
+ case srm_DECCKM:
+ bitcpy(&xw->keyboard.flags,
+ screen->save_modes[DP_DECCKM], MODE_DECCKM);
+ update_appcursor();
+ break;
+ case srm_DECANM: /* ANSI/VT52 mode */
+ /* no effect */
+ break;
+ case srm_DECCOLM:
+ if (screen->c132) {
+ if (!(xw->flags & NOCLEAR_COLM))
+ ClearScreen(xw);
+ CursorSet(screen, 0, 0, xw->flags);
+ if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS)
+ ? 132 : 80) != ((xw->flags & IN132COLUMNS)
+ ? 132 : 80) || j != MaxCols(screen))
+ RequestResize(xw, -1, j, True);
+ bitcpy(&xw->flags,
+ screen->save_modes[DP_DECCOLM],
+ IN132COLUMNS);
+ }
+ break;
+ case srm_DECSCLM: /* (slow scroll) */
+ if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) {
+ screen->jumpscroll = 0;
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ } else
+ screen->jumpscroll = 1;
+ bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL);
+ update_jumpscroll();
+ break;
+ case srm_DECSCNM:
+ if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) {
+ bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO);
+ ReverseVideo(xw);
+ /* update_reversevideo done in RevVid */
+ }
+ break;
+ case srm_DECOM:
+ bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN);
+ CursorSet(screen, 0, 0, xw->flags);
+ break;
+
+ case srm_DECAWM:
+ bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND);
+ update_autowrap();
+ break;
+ case srm_DECARM:
+ /* ignore autorepeat */
+ break;
+ case srm_X10_MOUSE: /* MIT bogus sequence */
+ DoRM0(DP_X_X10MSE, screen->send_mouse_pos);
+ really_set_mousemode(xw,
+ screen->send_mouse_pos != MOUSE_OFF,
+ screen->send_mouse_pos);
+ break;
+#if OPT_TOOLBAR
+ case srm_RXVT_TOOLBAR:
+ DoRM(DP_TOOLBAR, resource.toolBar);
+ ShowToolbar(resource.toolBar);
+ break;
+#endif
+#if OPT_BLINK_CURS
+ case srm_ATT610_BLINK: /* Start/stop blinking cursor */
+ if (screen->cursor_blink_res) {
+ DoRM(DP_CRS_BLINK, screen->cursor_blink_esc);
+ UpdateCursorBlink(screen);
+ }
+ break;
+#endif
+ case srm_DECPFF: /* print form feed */
+ DoRM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed);
+ break;
+ case srm_DECPEX: /* print extent */
+ DoRM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent);
+ break;
+ case srm_DECTCEM: /* Show/hide cursor (VT200) */
+ DoRM(DP_CRS_VISIBLE, screen->cursor_set);
+ break;
+ case srm_RXVT_SCROLLBAR:
+ if ((screen->fullVwin.sb_info.width != 0) !=
+ screen->save_modes[DP_RXVT_SCROLLBAR]) {
+ ToggleScrollBar(xw);
+ }
+ break;
+#if OPT_SHIFT_FONTS
+ case srm_RXVT_FONTSIZE:
+ DoRM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts);
+ break;
+#endif
+#if OPT_TEK4014
+ case srm_DECTEK:
+ if (!(screen->inhibit & I_TEK) &&
+ (TEK4014_ACTIVE(xw) != (Boolean) screen->save_modes[DP_DECTEK])) {
+ FlushLog(xw);
+ TEK4014_ACTIVE(xw) = (Boolean) screen->save_modes[DP_DECTEK];
+ }
+ break;
+#endif
+ case srm_132COLS: /* 132 column mode */
+ DoRM(DP_X_DECCOLM, screen->c132);
+ update_allow132();
+ break;
+ case srm_CURSES_HACK: /* curses hack */
+ DoRM(DP_X_MORE, screen->curses);
+ update_cursesemul();
+ break;
+ case srm_DECNRCM: /* national charset (VT220) */
+ bitcpy(&xw->flags, screen->save_modes[DP_DECNRCM], NATIONAL);
+ break;
+ case srm_MARGIN_BELL: /* margin bell */
+ if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0)
+ screen->bellArmed = -1;
+ update_marginbell();
+ break;
+ case srm_REVERSEWRAP: /* reverse wraparound */
+ bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP);
+ update_reversewrap();
+ break;
+#ifdef ALLOWLOGGING
+ case srm_ALLOWLOGGING: /* logging */
+#ifdef ALLOWLOGFILEONOFF
+ if (screen->save_modes[DP_X_LOGGING])
+ StartLog(xw);
+ else
+ CloseLog(xw);
+#endif /* ALLOWLOGFILEONOFF */
+ /* update_logging done by StartLog and CloseLog */
+ break;
+#endif
+ case srm_OPT_ALTBUF_CURSOR: /* alternate buffer & cursor */
+ /* FALLTHRU */
+ case srm_OPT_ALTBUF:
+ /* FALLTHRU */
+ case srm_ALTBUF: /* alternate buffer */
+ if (!xw->misc.titeInhibit) {
+ if (screen->save_modes[DP_X_ALTSCRN])
+ ToAlternate(xw);
+ else
+ FromAlternate(xw);
+ /* update_altscreen done by ToAlt and FromAlt */
+ } else if (xw->misc.tiXtraScroll) {
+ if (screen->save_modes[DP_X_ALTSCRN]) {
+ xtermScroll(xw, screen->max_row);
+ }
+ }
+ break;
+ case srm_DECNKM:
+ bitcpy(&xw->flags, screen->save_modes[DP_DECKPAM], MODE_DECKPAM);
+ update_appkeypad();
+ break;
+ case srm_DECBKM:
+ bitcpy(&xw->flags, screen->save_modes[DP_DECBKM], MODE_DECBKM);
+ update_decbkm();
+ break;
+ case srm_DECLRMM: /* left-right */
+ bitcpy(&xw->flags, screen->save_modes[DP_X_LRMM], LEFT_RIGHT);
+ if (IsLeftRightMode(xw)) {
+ xterm_ResetDouble(xw);
+ } else {
+ reset_lr_margins(screen);
+ }
+ CursorSet(screen, 0, 0, xw->flags);
+ break;
+ case srm_DECNCSM: /* noclear */
+ bitcpy(&xw->flags, screen->save_modes[DP_X_NCSM], NOCLEAR_COLM);
+ break;
+ case srm_VT200_MOUSE: /* mouse bogus sequence */
+ case srm_VT200_HIGHLIGHT_MOUSE:
+ case srm_BTN_EVENT_MOUSE:
+ case srm_ANY_EVENT_MOUSE:
+ DoRM0(DP_X_MOUSE, screen->send_mouse_pos);
+ really_set_mousemode(xw,
+ screen->send_mouse_pos != MOUSE_OFF,
+ screen->send_mouse_pos);
+ break;
+#if OPT_FOCUS_EVENT
+ case srm_FOCUS_EVENT_MOUSE:
+ DoRM(DP_X_FOCUS, screen->send_focus_pos);
+ break;
+#endif
+ case srm_EXT_MODE_MOUSE:
+ /* FALLTHRU */
+ case srm_SGR_EXT_MODE_MOUSE:
+ /* FALLTHRU */
+ case srm_URXVT_EXT_MODE_MOUSE:
+ DoRM(DP_X_EXT_MOUSE, screen->extend_coords);
+ break;
+ case srm_TITE_INHIBIT:
+ if (!xw->misc.titeInhibit) {
+ CursorRestore(xw);
+ }
+ break;
+ case srm_RXVT_SCROLL_TTY_OUTPUT:
+ DoRM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput);
+ update_scrollttyoutput();
+ break;
+ case srm_RXVT_SCROLL_TTY_KEYPRESS:
+ DoRM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey);
+ update_scrollkey();
+ break;
+ case srm_EIGHT_BIT_META:
+ DoRM(DP_EIGHT_BIT_META, screen->eight_bit_meta);
+ break;
+#if OPT_NUM_LOCK
+ case srm_REAL_NUMLOCK:
+ DoRM(DP_REAL_NUMLOCK, xw->misc.real_NumLock);
+ update_num_lock();
+ break;
+ case srm_META_SENDS_ESC:
+ DoRM(DP_META_SENDS_ESC, screen->meta_sends_esc);
+ update_meta_esc();
+ break;
+#endif
+ case srm_DELETE_IS_DEL:
+ DoRM(DP_DELETE_IS_DEL, screen->delete_is_del);
+ update_delete_del();
+ break;
+#if OPT_NUM_LOCK
+ case srm_ALT_SENDS_ESC:
+ DoRM(DP_ALT_SENDS_ESC, screen->alt_sends_esc);
+ update_alt_esc();
+ break;
+#endif
+ case srm_KEEP_SELECTION:
+ DoRM(DP_KEEP_SELECTION, screen->keepSelection);
+ update_keepSelection();
+ break;
+ case srm_SELECT_TO_CLIPBOARD:
+ DoRM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard);
+ update_selectToClipboard();
+ break;
+ case srm_BELL_IS_URGENT:
+ DoRM(DP_BELL_IS_URGENT, screen->bellIsUrgent);
+ update_bellIsUrgent();
+ break;
+ case srm_POP_ON_BELL:
+ DoRM(DP_POP_ON_BELL, screen->poponbell);
+ update_poponbell();
+ break;
+#if OPT_TCAP_FKEYS
+ case srm_TCAP_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_SUN_FUNC_KEYS
+ case srm_SUN_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_HP_FUNC_KEYS
+ case srm_HP_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_SCO_FUNC_KEYS
+ case srm_SCO_FKEYS:
+ /* FALLTHRU */
+#endif
+#if OPT_SUNPC_KBD
+ case srm_VT220_FKEYS:
+ /* FALLTHRU */
+#endif
+ case srm_LEGACY_FKEYS:
+ xw->keyboard.type = (xtermKeyboardType) screen->save_modes[DP_KEYBOARD_TYPE];
+ break;
+#if OPT_READLINE
+ case srm_BUTTON1_MOVE_POINT:
+ SCREEN_FLAG_restore(screen, click1_moves);
+ break;
+ case srm_BUTTON2_MOVE_POINT:
+ SCREEN_FLAG_restore(screen, paste_moves);
+ break;
+ case srm_DBUTTON3_DELETE:
+ SCREEN_FLAG_restore(screen, dclick3_deletes);
+ break;
+ case srm_PASTE_IN_BRACKET:
+ SCREEN_FLAG_restore(screen, paste_brackets);
+ break;
+ case srm_PASTE_QUOTE:
+ SCREEN_FLAG_restore(screen, paste_quotes);
+ break;
+ case srm_PASTE_LITERAL_NL:
+ SCREEN_FLAG_restore(screen, paste_literal_nl);
+ break;
+#endif /* OPT_READLINE */
+ }
+ }
+}
+
+/*
+ * Convert an XTextProperty to a string.
+ *
+ * This frees the data owned by the XTextProperty, and returns in its place the
+ * string, which must be freed by the caller.
+ */
+static char *
+property_to_string(XtermWidget xw, XTextProperty * text)
+{
+ TScreen *screen = TScreenOf(xw);
+ Display *dpy = screen->display;
+ char *result = 0;
+ char **list;
+ int length = 0;
+ int rc;
+
+ TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n",
+ text->value,
+ XGetAtomName(dpy, text->encoding),
+ text->format,
+ text->nitems));
+
+#if OPT_WIDE_CHARS
+ /*
+ * We will use the XmbTextPropertyToTextList call to extract UTF-8 data.
+ * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to
+ * ISO-8859-1.
+ */
+ if ((text->format != 8)
+ || IsTitleMode(xw, tmGetUtf8)
+ || (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0)
+#endif
+ if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0)
+ rc = XTextPropertyToStringList(text, &list, &length);
+
+ if (rc >= 0) {
+ int n, c, pass;
+ size_t need = 0;
+
+ for (pass = 0; pass < 2; ++pass) {
+ for (n = 0, need = 0; n < length; n++) {
+ char *s = list[n];
+ while ((c = *s++) != '\0') {
+ if (pass)
+ result[need] = (char) c;
+ ++need;
+ }
+ }
+ if (pass)
+ result[need] = '\0';
+ else
+ result = malloc(need + 1);
+ if (result == 0)
+ break;
+ }
+ XFreeStringList(list);
+ }
+ if (text->value != 0)
+ XFree(text->value);
+
+ return result;
+}
+
+static char *
+get_icon_label(XtermWidget xw)
+{
+ XTextProperty text;
+ char *result = 0;
+
+ if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow(xw), &text)) {
+ result = property_to_string(xw, &text);
+ }
+ return result;
+}
+
+static char *
+get_window_label(XtermWidget xw)
+{
+ XTextProperty text;
+ char *result = 0;
+
+ if (XGetWMName(TScreenOf(xw)->display, VShellWindow(xw), &text)) {
+ result = property_to_string(xw, &text);
+ }
+ return result;
+}
+
+/*
+ * Report window label (icon or title) in dtterm protocol
+ * ESC ] code label ESC backslash
+ */
+static void
+report_win_label(XtermWidget xw,
+ int code,
+ char *text)
+{
+ unparseputc(xw, ANSI_ESC);
+ unparseputc(xw, ']');
+ unparseputc(xw, code);
+
+ if (text != 0) {
+ int copy = IsTitleMode(xw, tmGetBase16);
+ if (copy) {
+ TRACE(("Encoding hex:%s\n", text));
+ text = x_encode_hex(text);
+ }
+ unparseputs(xw, text);
+ if (copy)
+ free(text);
+ }
+
+ unparseputc(xw, ANSI_ESC);
+ unparseputc(xw, '\\'); /* should be ST */
+ unparse_end(xw);
+}
+
+/*
+ * Window operations (from CDE dtterm description, as well as extensions).
+ * See also "allowWindowOps" resource.
+ */
+static void
+window_ops(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ XWindowChanges values;
+ XWindowAttributes win_attrs;
+ unsigned value_mask;
+#if OPT_MAXIMIZE
+ unsigned root_width;
+ unsigned root_height;
+#endif
+
+ TRACE(("window_ops %d\n", param[0]));
+ switch (param[0]) {
+ case ewRestoreWin: /* Restore (de-iconify) window */
+ if (AllowWindowOps(xw, ewRestoreWin)) {
+ TRACE(("...de-iconify window\n"));
+ XMapWindow(screen->display,
+ VShellWindow(xw));
+ }
+ break;
+
+ case ewMinimizeWin: /* Minimize (iconify) window */
+ if (AllowWindowOps(xw, ewMinimizeWin)) {
+ TRACE(("...iconify window\n"));
+ XIconifyWindow(screen->display,
+ VShellWindow(xw),
+ DefaultScreen(screen->display));
+ }
+ break;
+
+ case ewSetWinPosition: /* Move the window to the given position */
+ if (AllowWindowOps(xw, ewSetWinPosition)) {
+ values.x = zero_if_default(1);
+ values.y = zero_if_default(2);
+ TRACE(("...move window to %d,%d\n", values.x, values.y));
+ value_mask = (CWX | CWY);
+ XReconfigureWMWindow(screen->display,
+ VShellWindow(xw),
+ DefaultScreen(screen->display),
+ value_mask,
+ &values);
+ }
+ break;
+
+ case ewSetWinSizePixels: /* Resize the window to given size in pixels */
+ if (AllowWindowOps(xw, ewSetWinSizePixels)) {
+ RequestResize(xw, param[1], param[2], False);
+ }
+ break;
+
+ case ewRaiseWin: /* Raise the window to the front of the stack */
+ if (AllowWindowOps(xw, ewRaiseWin)) {
+ TRACE(("...raise window\n"));
+ XRaiseWindow(screen->display, VShellWindow(xw));
+ }
+ break;
+
+ case ewLowerWin: /* Lower the window to the bottom of the stack */
+ if (AllowWindowOps(xw, ewLowerWin)) {
+ TRACE(("...lower window\n"));
+ XLowerWindow(screen->display, VShellWindow(xw));
+ }
+ break;
+
+ case ewRefreshWin: /* Refresh the window */
+ if (AllowWindowOps(xw, ewRefreshWin)) {
+ TRACE(("...redraw window\n"));
+ Redraw();
+ }
+ break;
+
+ case ewSetWinSizeChars: /* Resize the text-area, in characters */
+ if (AllowWindowOps(xw, ewSetWinSizeChars)) {
+ RequestResize(xw, param[1], param[2], True);
+ }
+ break;
+
+#if OPT_MAXIMIZE
+ case ewMaximizeWin: /* Maximize or restore */
+ if (AllowWindowOps(xw, ewMaximizeWin)) {
+ RequestMaximize(xw, zero_if_default(1));
+ }
+ break;
+ case ewFullscreenWin: /* Fullscreen or restore */
+ if (AllowWindowOps(xw, ewFullscreenWin)) {
+ FullScreen(xw, zero_if_default(1));
+ }
+ break;
+#endif
+
+ case ewGetWinState: /* Report the window's state */
+ if (AllowWindowOps(xw, ewGetWinState)) {
+ TRACE(("...get window attributes\n"));
+ XGetWindowAttributes(screen->display,
+ VWindow(screen),
+ &win_attrs);
+ init_reply(ANSI_CSI);
+ reply.a_pintro = 0;
+ reply.a_nparam = 1;
+ reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable)
+ ? 1
+ : 2);
+ reply.a_inters = 0;
+ reply.a_final = 't';
+ unparseseq(xw, &reply);
+ }
+ break;
+
+ case ewGetWinPosition: /* Report the window's position */
+ if (AllowWindowOps(xw, ewGetWinPosition)) {
+ TRACE(("...get window position\n"));
+ XGetWindowAttributes(screen->display,
+ WMFrameWindow(xw),
+ &win_attrs);
+ init_reply(ANSI_CSI);
+ reply.a_pintro = 0;
+ reply.a_nparam = 3;
+ reply.a_param[0] = 3;
+ reply.a_param[1] = (ParmType) win_attrs.x;
+ reply.a_param[2] = (ParmType) win_attrs.y;
+ reply.a_inters = 0;
+ reply.a_final = 't';
+ unparseseq(xw, &reply);
+ }
+ break;
+
+ case ewGetWinSizePixels: /* Report the window's size in pixels */
+ if (AllowWindowOps(xw, ewGetWinSizePixels)) {
+ TRACE(("...get window size in pixels\n"));
+ XGetWindowAttributes(screen->display,
+ VWindow(screen),
+ &win_attrs);
+ init_reply(ANSI_CSI);
+ reply.a_pintro = 0;
+ reply.a_nparam = 3;
+ reply.a_param[0] = 4;
+ /*FIXME: find if dtterm uses
+ * win_attrs.height or Height
+ * win_attrs.width or Width
+ */
+ reply.a_param[1] = (ParmType) Height(screen);
+ reply.a_param[2] = (ParmType) Width(screen);
+ reply.a_inters = 0;
+ reply.a_final = 't';
+ unparseseq(xw, &reply);
+ }
+ break;
+
+ case ewGetWinSizeChars: /* Report the text's size in characters */
+ if (AllowWindowOps(xw, ewGetWinSizeChars)) {
+ TRACE(("...get window size in characters\n"));
+ init_reply(ANSI_CSI);
+ reply.a_pintro = 0;
+ reply.a_nparam = 3;
+ reply.a_param[0] = 8;
+ reply.a_param[1] = (ParmType) MaxRows(screen);
+ reply.a_param[2] = (ParmType) MaxCols(screen);
+ reply.a_inters = 0;
+ reply.a_final = 't';
+ unparseseq(xw, &reply);
+ }
+ break;
+
+#if OPT_MAXIMIZE
+ case ewGetScreenSizeChars: /* Report the screen's size, in characters */
+ if (AllowWindowOps(xw, ewGetScreenSizeChars)) {
+ TRACE(("...get screen size in characters\n"));
+ if (!QueryMaximize(xw, &root_height, &root_width)) {
+ root_height = 0;
+ root_width = 0;
+ }
+ init_reply(ANSI_CSI);
+ reply.a_pintro = 0;
+ reply.a_nparam = 3;
+ reply.a_param[0] = 9;
+ reply.a_param[1] = (ParmType) (root_height
+ / (unsigned) FontHeight(screen));
+ reply.a_param[2] = (ParmType) (root_width
+ / (unsigned) FontWidth(screen));
+ reply.a_inters = 0;
+ reply.a_final = 't';
+ unparseseq(xw, &reply);
+ }
+ break;
+#endif
+
+ case ewGetIconTitle: /* Report the icon's label */
+ if (AllowWindowOps(xw, ewGetIconTitle)) {
+ TRACE(("...get icon's label\n"));
+ report_win_label(xw, 'L', get_icon_label(xw));
+ }
+ break;
+
+ case ewGetWinTitle: /* Report the window's title */
+ if (AllowWindowOps(xw, ewGetWinTitle)) {
+ TRACE(("...get window's label\n"));
+ report_win_label(xw, 'l', get_window_label(xw));
+ }
+ break;
+
+ case ewPushTitle: /* save the window's title(s) on stack */
+ if (AllowWindowOps(xw, ewPushTitle)) {
+ SaveTitle *last = screen->save_title;
+ SaveTitle *item = TypeCalloc(SaveTitle);
+
+ TRACE(("...push title onto stack\n"));
+ if (item != 0) {
+ switch (zero_if_default(1)) {
+ case 0:
+ item->iconName = get_icon_label(xw);
+ item->windowName = get_window_label(xw);
+ break;
+ case 1:
+ item->iconName = get_icon_label(xw);
+ break;
+ case 2:
+ item->windowName = get_window_label(xw);
+ break;
+ }
+ item->next = last;
+ if (item->iconName == 0) {
+ item->iconName = ((last == 0)
+ ? get_icon_label(xw)
+ : x_strdup(last->iconName));
+ }
+ if (item->windowName == 0) {
+ item->windowName = ((last == 0)
+ ? get_window_label(xw)
+ : x_strdup(last->windowName));
+ }
+ screen->save_title = item;
+ }
+ }
+ break;
+
+ case ewPopTitle: /* restore the window's title(s) from stack */
+ if (AllowWindowOps(xw, ewPopTitle)) {
+ SaveTitle *item = screen->save_title;
+
+ TRACE(("...pop title off stack\n"));
+ if (item != 0) {
+ switch (zero_if_default(1)) {
+ case 0:
+ ChangeIconName(xw, item->iconName);
+ ChangeTitle(xw, item->windowName);
+ break;
+ case 1:
+ ChangeIconName(xw, item->iconName);
+ break;
+ case 2:
+ ChangeTitle(xw, item->windowName);
+ break;
+ }
+ screen->save_title = item->next;
+ free(item->iconName);
+ free(item->windowName);
+ free(item);
+ }
+ }
+ break;
+
+ default: /* DECSLPP (24, 25, 36, 48, 72, 144) */
+ if (AllowWindowOps(xw, ewSetWinLines)) {
+ if (param[0] >= 24)
+ RequestResize(xw, param[0], -1, True);
+ }
+ break;
+ }
+}
+
+/*
+ * set a bit in a word given a pointer to the word and a mask.
+ */
+static void
+bitset(unsigned *p, unsigned mask)
+{
+ *p |= mask;
+}
+
+/*
+ * clear a bit in a word given a pointer to the word and a mask.
+ */
+static void
+bitclr(unsigned *p, unsigned mask)
+{
+ *p &= ~mask;
+}
+
+/*
+ * Copy bits from one word to another, given a mask
+ */
+static void
+bitcpy(unsigned *p, unsigned q, unsigned mask)
+{
+ bitclr(p, mask);
+ bitset(p, q & mask);
+}
+
+void
+unparseputc1(XtermWidget xw, int c)
+{
+ if (c >= 0x80 && c <= 0x9F) {
+ if (!TScreenOf(xw)->control_eight_bits) {
+ unparseputc(xw, A2E(ANSI_ESC));
+ c = A2E(c - 0x40);
+ }
+ }
+ unparseputc(xw, c);
+}
+
+void
+unparseseq(XtermWidget xw, ANSI * ap)
+{
+ int c;
+ int i;
+ int inters;
+
+ unparseputc1(xw, c = ap->a_type);
+ if (c == ANSI_ESC
+ || c == ANSI_DCS
+ || c == ANSI_CSI
+ || c == ANSI_OSC
+ || c == ANSI_PM
+ || c == ANSI_APC
+ || c == ANSI_SS3) {
+ if (ap->a_pintro != 0)
+ unparseputc(xw, ap->a_pintro);
+ for (i = 0; i < ap->a_nparam; ++i) {
+ if (i != 0) {
+ if (ap->a_delim) {
+ unparseputs(xw, ap->a_delim);
+ } else {
+ unparseputc(xw, ';');
+ }
+ }
+ if (ap->a_radix[i]) {
+ char temp[8];
+ sprintf(temp, "%04X", ap->a_param[i] & 0xffff);
+ unparseputs(xw, temp);
+ } else {
+ unparseputn(xw, (unsigned int) ap->a_param[i]);
+ }
+ }
+ if ((inters = ap->a_inters) != 0) {
+ for (i = 3; i >= 0; --i) {
+ c = CharOf(inters >> (8 * i));
+ if (c != 0)
+ unparseputc(xw, c);
+ }
+ }
+ switch (ap->a_type) {
+ case ANSI_DCS:
+ case ANSI_OSC:
+ case ANSI_PM:
+ case ANSI_APC:
+ unparseputc1(xw, ANSI_ST);
+ break;
+ default:
+ unparseputc(xw, (char) ap->a_final);
+ break;
+ }
+ }
+ unparse_end(xw);
+}
+
+void
+unparseputn(XtermWidget xw, unsigned int n)
+{
+ unsigned int q;
+
+ q = n / 10;
+ if (q != 0)
+ unparseputn(xw, q);
+ unparseputc(xw, (char) ('0' + (n % 10)));
+}
+
+void
+unparseputs(XtermWidget xw, const char *s)
+{
+ if (s != 0) {
+ while (*s)
+ unparseputc(xw, *s++);
+ }
+}
+
+void
+unparseputc(XtermWidget xw, int c)
+{
+ TScreen *screen = TScreenOf(xw);
+ IChar *buf = screen->unparse_bfr;
+ unsigned len;
+
+ if ((screen->unparse_len + 2) >= sizeof(screen->unparse_bfr))
+ unparse_end(xw);
+
+ len = screen->unparse_len;
+
+#if OPT_TCAP_QUERY
+ /*
+ * If we're returning a termcap string, it has to be translated since
+ * a DCS must not contain any characters except for the normal 7-bit
+ * printable ASCII (counting tab, carriage return, etc). For now,
+ * just use hexadecimal for the whole thing.
+ */
+ if (screen->tc_query_code >= 0) {
+ char tmp[3];
+ sprintf(tmp, "%02X", c & 0xFF);
+ buf[len++] = CharOf(tmp[0]);
+ buf[len++] = CharOf(tmp[1]);
+ } else
+#endif
+ if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) {
+ buf[len++] = '\n';
+ }
+
+ screen->unparse_len = len;
+
+ /* If send/receive mode is reset, we echo characters locally */
+ if ((xw->keyboard.flags & MODE_SRM) == 0) {
+ (void) doparsing(xw, (unsigned) c, &myState);
+ }
+}
+
+void
+unparse_end(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+
+ if (screen->unparse_len) {
+#ifdef VMS
+ tt_write(screen->unparse_bfr, screen->unparse_len);
+#else /* VMS */
+ writePtyData(screen->respond, screen->unparse_bfr, screen->unparse_len);
+#endif /* VMS */
+ screen->unparse_len = 0;
+ }
+}
+
+void
+ToggleAlternate(XtermWidget xw)
+{
+ if (TScreenOf(xw)->whichBuf)
+ FromAlternate(xw);
+ else
+ ToAlternate(xw);
+}
+
+static void
+ToAlternate(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+
+ if (screen->whichBuf == 0) {
+ TRACE(("ToAlternate\n"));
+ if (!screen->editBuf_index[1])
+ screen->editBuf_index[1] = allocScrnBuf(xw,
+ (unsigned) MaxRows(screen),
+ (unsigned) MaxCols(screen),
+ &screen->editBuf_data[1]);
+ SwitchBufs(xw, 1);
+ screen->whichBuf = 1;
+#if OPT_SAVE_LINES
+ screen->visbuf = screen->editBuf_index[screen->whichBuf];
+#endif
+ update_altscreen();
+ }
+}
+
+static void
+FromAlternate(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+
+ if (screen->whichBuf != 0) {
+ TRACE(("FromAlternate\n"));
+ if (screen->scroll_amt)
+ FlushScroll(xw);
+ screen->whichBuf = 0;
+ SwitchBufs(xw, 0);
+#if OPT_SAVE_LINES
+ screen->visbuf = screen->editBuf_index[screen->whichBuf];
+#endif
+ update_altscreen();
+ }
+}
+
+static void
+SwitchBufs(XtermWidget xw, int toBuf)
+{
+ TScreen *screen = TScreenOf(xw);
+ int rows, top;
+
+ if (screen->cursor_state)
+ HideCursor();
+
+ rows = MaxRows(screen);
+ SwitchBufPtrs(screen, toBuf);
+
+ if ((top = INX2ROW(screen, 0)) < rows) {
+ if (screen->scroll_amt) {
+ FlushScroll(xw);
+ }
+ XClearArea(screen->display,
+ VWindow(screen),
+ (int) OriginX(screen),
+ (int) top * FontHeight(screen) + screen->border,
+ (unsigned) Width(screen),
+ (unsigned) ((rows - top) * FontHeight(screen)),
+ False);
+ }
+ ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False);
+}
+
+Bool
+CheckBufPtrs(TScreen * screen)
+{
+ return (screen->visbuf != 0
+#if OPT_SAVE_LINES
+ && screen->editBuf_index[0] != 0
+#endif
+ && screen->editBuf_index[1] != 0);
+}
+
+/*
+ * Swap buffer line pointers between alternate and regular screens.
+ */
+void
+SwitchBufPtrs(TScreen * screen, int toBuf GCC_UNUSED)
+{
+ if (CheckBufPtrs(screen)) {
+#if OPT_SAVE_LINES
+ screen->visbuf = screen->editBuf_index[toBuf];
+#else
+ size_t len = ScrnPointers(screen, (size_t) MaxRows(screen));
+
+ memcpy(screen->save_ptr, screen->visbuf, len);
+ memcpy(screen->visbuf, screen->editBuf_index[1], len);
+ memcpy(screen->editBuf_index[1], screen->save_ptr, len);
+#endif
+ }
+}
+
+void
+VTRun(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+
+ TRACE(("VTRun ...\n"));
+
+ if (!screen->Vshow) {
+ set_vt_visibility(True);
+ }
+ update_vttekmode();
+ update_vtshow();
+ update_tekshow();
+ set_vthide_sensitivity();
+
+ ScrnAllocBuf(xw);
+
+ screen->cursor_state = OFF;
+ screen->cursor_set = ON;
+#if OPT_BLINK_CURS
+ if (DoStartBlinking(screen))
+ StartBlinking(screen);
+#endif
+
+#if OPT_TEK4014
+ if (Tpushb > Tpushback) {
+ fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback));
+ Tpushb = Tpushback;
+ }
+#endif
+ screen->is_running = True;
+ if (screen->embed_high && screen->embed_wide) {
+ ScreenResize(xw, screen->embed_wide, screen->embed_high, &(xw->flags));
+ }
+#if OPT_MAXIMIZE
+ else if (resource.fullscreen == esTrue || resource.fullscreen == esAlways)
+ FullScreen(term, True);
+#endif
+ if (!setjmp(VTend))
+ VTparse(xw);
+ StopBlinking(screen);
+ HideCursor();
+ screen->cursor_set = OFF;
+ TRACE(("... VTRun\n"));
+}
+
+/*ARGSUSED*/
+static void
+VTExpose(Widget w GCC_UNUSED,
+ XEvent * event,
+ Region region GCC_UNUSED)
+{
+#ifdef DEBUG
+ if (debug)
+ fputs("Expose\n", stderr);
+#endif /* DEBUG */
+ if (event->type == Expose)
+ HandleExposure(term, event);
+}
+
+static void
+VTGraphicsOrNoExpose(XEvent * event)
+{
+ TScreen *screen = TScreenOf(term);
+ if (screen->incopy <= 0) {
+ screen->incopy = 1;
+ if (screen->scrolls > 0)
+ screen->scrolls--;
+ }
+ if (event->type == GraphicsExpose)
+ if (HandleExposure(term, event))
+ screen->cursor_state = OFF;
+ if ((event->type == NoExpose)
+ || ((XGraphicsExposeEvent *) event)->count == 0) {
+ if (screen->incopy <= 0 && screen->scrolls > 0)
+ screen->scrolls--;
+ if (screen->scrolls)
+ screen->incopy = -1;
+ else
+ screen->incopy = 0;
+ }
+}
+
+/*ARGSUSED*/
+static void
+VTNonMaskableEvent(Widget w GCC_UNUSED,
+ XtPointer closure GCC_UNUSED,
+ XEvent * event,
+ Boolean * cont GCC_UNUSED)
+{
+ switch (event->type) {
+ case GraphicsExpose:
+ case NoExpose:
+ VTGraphicsOrNoExpose(event);
+ break;
+ }
+}
+
+static void
+VTResize(Widget w)
+{
+ if (XtIsRealized(w)) {
+ XtermWidget xw = (XtermWidget) w;
+ ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags);
+ }
+}
+
+#define okDimension(src,dst) ((src <= 32767) \
+ && ((dst = (Dimension) src) == src))
+
+static void
+RequestResize(XtermWidget xw, int rows, int cols, Bool text)
+{
+ TScreen *screen = TScreenOf(xw);
+ unsigned long value;
+ Dimension replyWidth, replyHeight;
+ Dimension askedWidth, askedHeight;
+ XtGeometryResult status;
+ XWindowAttributes attrs;
+
+ TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text));
+
+ if ((int) (askedWidth = (Dimension) cols) < cols
+ || (int) (askedHeight = (Dimension) rows) < rows)
+ return;
+
+ if (askedHeight == 0
+ || askedWidth == 0
+ || xw->misc.limit_resize > 0) {
+ XGetWindowAttributes(XtDisplay(xw),
+ RootWindowOfScreen(XtScreen(xw)), &attrs);
+ }
+
+ if (text) {
+ if ((value = (unsigned long) rows) != 0) {
+ if (rows < 0)
+ value = (unsigned long) MaxRows(screen);
+ value *= (unsigned long) FontHeight(screen);
+ value += (unsigned long) (2 * screen->border);
+ if (!okDimension(value, askedHeight))
+ return;
+ }
+
+ if ((value = (unsigned long) cols) != 0) {
+ if (cols < 0)
+ value = (unsigned long) MaxCols(screen);
+ value *= (unsigned long) FontWidth(screen);
+ value += (unsigned long) ((2 * screen->border)
+ + ScrollbarWidth(screen));
+ if (!okDimension(value, askedWidth))
+ return;
+ }
+
+ } else {
+ if (rows < 0)
+ askedHeight = FullHeight(screen);
+ if (cols < 0)
+ askedWidth = FullWidth(screen);
+ }
+
+ if (rows == 0)
+ askedHeight = (Dimension) attrs.height;
+ if (cols == 0)
+ askedWidth = (Dimension) attrs.width;
+
+ if (xw->misc.limit_resize > 0) {
+ Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height);
+ Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width);
+ if ((int) high < attrs.height)
+ high = (Dimension) attrs.height;
+ if (askedHeight > high)
+ askedHeight = high;
+ if ((int) wide < attrs.width)
+ wide = (Dimension) attrs.width;
+ if (askedWidth > wide)
+ askedWidth = wide;
+ }
+#ifndef nothack
+ getXtermSizeHints(xw);
+#endif
+
+ TRACE(("...requesting resize %dx%d\n", askedHeight, askedWidth));
+ status = REQ_RESIZE((Widget) xw,
+ askedWidth, askedHeight,
+ &replyWidth, &replyHeight);
+
+ if (status == XtGeometryYes ||
+ status == XtGeometryDone) {
+ ScreenResize(xw, replyWidth, replyHeight, &xw->flags);
+ }
+#ifndef nothack
+ /*
+ * XtMakeResizeRequest() has the undesirable side-effect of clearing
+ * the window manager's hints, even on a failed request. This would
+ * presumably be fixed if the shell did its own work.
+ */
+ if (xw->hints.flags
+ && replyHeight
+ && replyWidth) {
+ xw->hints.height = replyHeight;
+ xw->hints.width = replyWidth;
+
+ TRACE(("%s@%d -- ", __FILE__, __LINE__));
+ TRACE_HINTS(&xw->hints);
+ XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints);
+ TRACE(("%s@%d -- ", __FILE__, __LINE__));
+ TRACE_WM_HINTS(xw);
+ }
+#endif
+
+ XSync(screen->display, False); /* synchronize */
+ if (xtermAppPending())
+ xevents();
+
+ TRACE(("...RequestResize done\n"));
+}
+
+static String xterm_trans =
+"<ClientMessage>WM_PROTOCOLS: DeleteWindow()\n\
+ <MappingNotify>: KeyboardMapping()\n";
+
+int
+VTInit(XtermWidget xw)
+{
+ Widget vtparent = SHELL_OF(xw);
+
+ TRACE(("VTInit {{\n"));
+
+ XtRealizeWidget(vtparent);
+ XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans));
+ (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent),
+ &wm_delete_window, 1);
+ TRACE_TRANS("shell", vtparent);
+ TRACE_TRANS("vt100", (Widget) (xw));
+
+ ScrnAllocBuf(xw);
+
+ TRACE(("...}} VTInit\n"));
+ return (1);
+}
+
+static void
+VTClassInit(void)
+{
+ XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity,
+ (XtConvertArgList) NULL, (Cardinal) 0);
+}
+
+#if OPT_COLOR_RES
+/*
+ * Override the use of XtDefaultForeground/XtDefaultBackground to make some
+ * colors, such as cursor color, use the actual foreground/background value
+ * if there is no explicit resource value used.
+ */
+static Pixel
+fill_Tres(XtermWidget target, XtermWidget source, int offset)
+{
+ char *name;
+ ScrnColors temp;
+
+ TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset];
+ TScreenOf(target)->Tcolors[offset].mode = False;
+
+ if ((name = x_strtrim(TScreenOf(target)->Tcolors[offset].resource)) != 0)
+ TScreenOf(target)->Tcolors[offset].resource = name;
+
+ if (name == 0) {
+ TScreenOf(target)->Tcolors[offset].value = target->dft_foreground;
+ } else if (isDefaultForeground(name)) {
+ TScreenOf(target)->Tcolors[offset].value =
+ ((offset == TEXT_FG || offset == TEXT_BG)
+ ? target->dft_foreground
+ : TScreenOf(target)->Tcolors[TEXT_FG].value);
+ } else if (isDefaultBackground(name)) {
+ TScreenOf(target)->Tcolors[offset].value =
+ ((offset == TEXT_FG || offset == TEXT_BG)
+ ? target->dft_background
+ : TScreenOf(target)->Tcolors[TEXT_BG].value);
+ } else {
+ memset(&temp, 0, sizeof(temp));
+ if (AllocateTermColor(target, &temp, offset, name, True)) {
+ if (COLOR_DEFINED(&(temp), offset))
+ free(temp.names[offset]);
+ TScreenOf(target)->Tcolors[offset].value = temp.colors[offset];
+ }
+ }
+ return TScreenOf(target)->Tcolors[offset].value;
+}
+#else
+#define fill_Tres(target, source, offset) \
+ TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset]
+#endif
+
+#if OPT_WIDE_CHARS
+static void
+VTInitialize_locale(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ Bool is_utf8 = xtermEnvUTF8();
+
+ TRACE(("VTInitialize_locale\n"));
+ TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode));
+ TRACE(("... request screen.utf8_fonts = %d\n", screen->utf8_fonts));
+
+ if (screen->utf8_mode < 0)
+ screen->utf8_mode = uFalse;
+
+ if (screen->utf8_mode > 3)
+ screen->utf8_mode = uDefault;
+
+ screen->latin9_mode = 0;
+ screen->unicode_font = 0;
+#if OPT_LUIT_PROG
+ xw->misc.callfilter = 0;
+ xw->misc.use_encoding = 0;
+
+ TRACE(("... setup for luit:\n"));
+ TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str));
+
+ if (screen->utf8_mode == uFalse) {
+ TRACE(("... command-line +u8 overrides\n"));
+ } else
+#if OPT_MINI_LUIT
+ if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) {
+ int fl = (xw->misc.default_font.f_n
+ ? (int) strlen(xw->misc.default_font.f_n)
+ : 0);
+ if (fl > 11
+ && x_strcasecmp(xw->misc.default_font.f_n + fl - 11,
+ "-ISO10646-1") == 0) {
+ screen->unicode_font = 1;
+ /* unicode font, use True */
+#ifdef HAVE_LANGINFO_CODESET
+ if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968")
+ || !strcmp(xtermEnvEncoding(), "ISO-8859-1")) {
+ if (screen->utf8_mode == uDefault)
+ screen->utf8_mode = uFalse;
+ } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) {
+ if (screen->utf8_mode == uDefault)
+ screen->utf8_mode = uFalse;
+ screen->latin9_mode = 1;
+ } else {
+ xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
+ screen->utf8_mode = uAlways;
+ }
+#else
+ xw->misc.callfilter = is_utf8 ? 0 : 1;
+ screen->utf8_mode = uAlways;
+#endif
+ } else {
+ /* other encoding, use False */
+ if (screen->utf8_mode == uDefault) {
+ screen->utf8_mode = is_utf8 ? uAlways : uFalse;
+ }
+ }
+ } else
+#endif /* OPT_MINI_LUIT */
+ if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "ON") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "YES") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 ||
+ strcmp(xw->misc.locale_str, "1") == 0) {
+ /* when true ... fully obeying LC_CTYPE locale */
+ xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1);
+ screen->utf8_mode = uAlways;
+ } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "OFF") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "NO") == 0 ||
+ strcmp(xw->misc.locale_str, "0") == 0) {
+ /* when false ... original value of utf8_mode is effective */
+ if (screen->utf8_mode == uDefault) {
+ screen->utf8_mode = is_utf8 ? uAlways : uFalse;
+ }
+ } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) {
+ /* when medium ... obeying locale only for UTF-8 and Asian */
+ if (is_utf8) {
+ screen->utf8_mode = uAlways;
+ } else if (
+#ifdef MB_CUR_MAX
+ MB_CUR_MAX > 1 ||
+#else
+ !strncmp(xtermEnvLocale(), "ja", (size_t) 2) ||
+ !strncmp(xtermEnvLocale(), "ko", (size_t) 2) ||
+ !strncmp(xtermEnvLocale(), "zh", (size_t) 2) ||
+#endif
+ !strncmp(xtermEnvLocale(), "th", (size_t) 2) ||
+ !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) {
+ xw->misc.callfilter = 1;
+ screen->utf8_mode = uAlways;
+ } else {
+ screen->utf8_mode = uFalse;
+ }
+ } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 ||
+ x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) {
+ /* when UTF-8 ... UTF-8 mode */
+ screen->utf8_mode = uAlways;
+ } else {
+ /* other words are regarded as encoding name passed to luit */
+ xw->misc.callfilter = 1;
+ screen->utf8_mode = uAlways;
+ xw->misc.use_encoding = 1;
+ }
+ TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter)));
+ TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding)));
+#else
+ if (screen->utf8_mode == uDefault) {
+ screen->utf8_mode = is_utf8 ? uAlways : uFalse;
+ }
+#endif /* OPT_LUIT_PROG */
+
+ if (screen->utf8_fonts == uDefault) {
+ switch (screen->utf8_mode) {
+ case uFalse:
+ case uTrue:
+ screen->utf8_fonts = screen->utf8_mode;
+ break;
+ case uDefault:
+ /* should not happen */
+ screen->utf8_fonts = uTrue;
+ break;
+ case uAlways:
+ /* use this to disable menu entry */
+ break;
+ }
+ }
+
+ screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse);
+
+ TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode));
+ TRACE(("... updated screen.utf8_fonts = %d\n", screen->utf8_fonts));
+ TRACE(("...VTInitialize_locale done\n"));
+}
+#endif
+
+void
+lookupSelectUnit(XtermWidget xw, Cardinal item, String value)
+{
+ /* *INDENT-OFF* */
+ static struct {
+ const char * name;
+ SelectUnit code;
+ } table[] = {
+ { "char", Select_CHAR },
+ { "word", Select_WORD },
+ { "line", Select_LINE },
+ { "group", Select_GROUP },
+ { "page", Select_PAGE },
+ { "all", Select_ALL },
+#if OPT_SELECT_REGEX
+ { "regex", Select_REGEX },
+#endif
+ };
+ /* *INDENT-ON* */
+
+ TScreen *screen = TScreenOf(xw);
+ String next = x_skip_nonblanks(value);
+ Cardinal n;
+
+ screen->selectMap[item] = NSELECTUNITS;
+ for (n = 0; n < XtNumber(table); ++n) {
+ if (!x_strncasecmp(table[n].name, value, (unsigned) (next - value))) {
+ screen->selectMap[item] = table[n].code;
+#if OPT_SELECT_REGEX
+ if (table[n].code == Select_REGEX) {
+ screen->selectExpr[item] = x_strtrim(next);
+ TRACE(("Parsed regex \"%s\"\n", screen->selectExpr[item]));
+ }
+#endif
+ break;
+ }
+ }
+}
+
+static void
+ParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item)
+{
+ lookupSelectUnit(wnew, item, TScreenOf(wreq)->onClick[item]);
+}
+
+/*
+ * Parse a comma-separated list, returning a string which the caller must
+ * free, and updating the source pointer.
+ */
+static char *
+ParseList(const char **source)
+{
+ const char *base = *source;
+ const char *next;
+ size_t size;
+ char *value = 0;
+ char *result;
+
+ /* ignore empty values */
+ while (*base == ',')
+ ++base;
+ if (*base != '\0') {
+ next = base;
+ while (*next != '\0' && *next != ',')
+ ++next;
+ size = (size_t) (1 + next - base);
+ value = malloc(size);
+ if (value != 0) {
+ memcpy(value, base, size);
+ value[size - 1] = '\0';
+ }
+ *source = next;
+ } else {
+ *source = base;
+ }
+ result = x_strtrim(value);
+ free(value);
+ return result;
+}
+
+static void
+set_flags_from_list(char *target,
+ const char *source,
+ FlagList * list,
+ Cardinal limit)
+{
+ Cardinal n;
+ int value = -1;
+
+ while (*source != '\0') {
+ char *next = ParseList(&source);
+ Boolean found = False;
+
+ if (next == 0)
+ break;
+ if (isdigit(CharOf(*next))) {
+ char *temp;
+
+ value = (int) strtol(next, &temp, 0);
+ if (!IsEmpty(temp)) {
+ xtermWarning("Expected a number: %s\n", next);
+ } else {
+ for (n = 0; n < limit; ++n) {
+ if (list[n].code == value) {
+ target[value] = 1;
+ found = True;
+ break;
+ }
+ }
+ }
+ } else {
+ for (n = 0; n < limit; ++n) {
+ if (!x_strcasecmp(next, list[n].name)) {
+ value = list[n].code;
+ target[value] = 1;
+ found = True;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ xtermWarning("Unrecognized keyword: %s\n", next);
+ } else {
+ TRACE(("...found %s (%d)\n", next, value));
+ }
+ free(next);
+ }
+}
+
+/* ARGSUSED */
+static void
+VTInitialize(Widget wrequest,
+ Widget new_arg,
+ ArgList args GCC_UNUSED,
+ Cardinal *num_args GCC_UNUSED)
+{
+#define Kolor(name) TScreenOf(wnew)->name.resource
+#define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name))
+#define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name))
+#define DftFg(name) isDefaultForeground(Kolor(name))
+#define DftBg(name) isDefaultBackground(Kolor(name))
+
+#define DATA(name) { #name, ec##name }
+ static FlagList tblColorOps[] =
+ {
+ DATA(SetColor)
+ ,DATA(GetColor)
+ ,DATA(GetAnsiColor)
+ };
+#undef DATA
+
+#define DATA(name) { #name, ef##name }
+ static FlagList tblFontOps[] =
+ {
+ DATA(SetFont)
+ ,DATA(GetFont)
+ };
+#undef DATA
+
+#define DATA(name) { #name, et##name }
+ static FlagList tblTcapOps[] =
+ {
+ DATA(SetTcap)
+ ,DATA(GetTcap)
+ };
+#undef DATA
+
+#define DATA(name) { #name, ew##name }
+ static FlagList tblWindowOps[] =
+ {
+ DATA(RestoreWin)
+ ,DATA(MinimizeWin)
+ ,DATA(SetWinPosition)
+ ,DATA(SetWinSizePixels)
+ ,DATA(RaiseWin)
+ ,DATA(LowerWin)
+ ,DATA(RefreshWin)
+ ,DATA(SetWinSizeChars)
+#if OPT_MAXIMIZE
+ ,DATA(MaximizeWin)
+ ,DATA(FullscreenWin)
+#endif
+ ,DATA(GetWinState)
+ ,DATA(GetWinPosition)
+ ,DATA(GetWinSizePixels)
+ ,DATA(GetWinSizeChars)
+#if OPT_MAXIMIZE
+ ,DATA(GetScreenSizeChars)
+#endif
+ ,DATA(GetIconTitle)
+ ,DATA(GetWinTitle)
+ ,DATA(PushTitle)
+ ,DATA(PopTitle)
+ ,DATA(SetWinLines)
+ ,DATA(SetXprop)
+ ,DATA(GetSelection)
+ ,DATA(SetSelection)
+ };
+#undef DATA
+
+#if OPT_RENDERFONT
+#define DATA(name) { #name, er##name }
+ static FlagList tblRenderFont[] =
+ {
+ DATA(Default)
+ };
+#undef DATA
+#endif
+
+#if OPT_WIDE_CHARS
+#define DATA(name) { #name, u##name }
+ static FlagList tblUtf8Mode[] =
+ {
+ DATA(Always)
+ ,DATA(Default)
+ };
+#undef DATA
+#endif
+
+#define DATA(name) { #name, eb##name }
+ static FlagList tbl8BitMeta[] =
+ {
+ DATA(Never)
+ ,DATA(Locale)
+ };
+#undef DATA
+
+ XtermWidget request = (XtermWidget) wrequest;
+ XtermWidget wnew = (XtermWidget) new_arg;
+ Widget my_parent = SHELL_OF(wnew);
+ int i;
+ const char *s;
+
+#if OPT_ISO_COLORS
+ Bool color_ok;
+#endif
+
+#if OPT_COLOR_RES2
+ static XtResource fake_resources[] =
+ {
+#if OPT_256_COLORS
+# include <256colres.h>
+#elif OPT_88_COLORS
+# include <88colres.h>
+#endif
+ };
+#endif /* OPT_COLOR_RES2 */
+
+ TRACE(("VTInitialize wnew %p, %d / %d resources\n",
+ (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES));
+ assert(XtNumber(xterm_resources) < MAXRESOURCES);
+
+ /* Zero out the entire "screen" component of "wnew" widget, then do
+ * field-by-field assignment of "screen" fields that are named in the
+ * resource list.
+ */
+ memset(TScreenOf(wnew), 0, sizeof(wnew->screen));
+
+ /* DESCO Sys#67660
+ * Zero out the entire "keyboard" component of "wnew" widget.
+ */
+ memset(&wnew->keyboard, 0, sizeof(wnew->keyboard));
+
+ /* dummy values so that we don't try to Realize the parent shell with height
+ * or width of 0, which is illegal in X. The real size is computed in the
+ * xtermWidget's Realize proc, but the shell's Realize proc is called first,
+ * and must see a valid size.
+ */
+ wnew->core.height = wnew->core.width = 1;
+
+ /*
+ * The definition of -rv now is that it changes the definition of
+ * XtDefaultForeground and XtDefaultBackground. So, we no longer
+ * need to do anything special.
+ */
+ TScreenOf(wnew)->display = wnew->core.screen->display;
+
+ /*
+ * We use the default foreground/background colors to compare/check if a
+ * color-resource has been set.
+ */
+#define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy))
+#define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy))
+
+ if (request->misc.re_verse) {
+ wnew->dft_foreground = MyWhitePixel(TScreenOf(wnew)->display);
+ wnew->dft_background = MyBlackPixel(TScreenOf(wnew)->display);
+ } else {
+ wnew->dft_foreground = MyBlackPixel(TScreenOf(wnew)->display);
+ wnew->dft_background = MyWhitePixel(TScreenOf(wnew)->display);
+ }
+
+ init_Tres(TEXT_FG);
+ init_Tres(TEXT_BG);
+
+ wnew->old_foreground = T_COLOR(TScreenOf(wnew), TEXT_FG);
+ wnew->old_background = T_COLOR(TScreenOf(wnew), TEXT_BG);
+
+ TRACE(("Color resource initialization:\n"));
+ TRACE((" Default foreground 0x%06lx\n", wnew->dft_foreground));
+ TRACE((" Default background 0x%06lx\n", wnew->dft_background));
+ TRACE((" Screen foreground 0x%06lx\n", T_COLOR(TScreenOf(wnew), TEXT_FG)));
+ TRACE((" Screen background 0x%06lx\n", T_COLOR(TScreenOf(wnew), TEXT_BG)));
+ TRACE((" Actual foreground 0x%06lx\n", wnew->old_foreground));
+ TRACE((" Actual background 0x%06lx\n", wnew->old_background));
+
+ TScreenOf(wnew)->mouse_button = -1;
+ TScreenOf(wnew)->mouse_row = -1;
+ TScreenOf(wnew)->mouse_col = -1;
+
+#if OPT_BOX_CHARS
+ init_Bres(screen.force_box_chars);
+ init_Bres(screen.force_packed);
+ init_Bres(screen.force_all_chars);
+#endif
+ init_Bres(screen.free_bold_box);
+ init_Bres(screen.allowBoldFonts);
+
+ init_Bres(screen.c132);
+ init_Bres(screen.curses);
+ init_Bres(screen.hp_ll_bc);
+#if OPT_XMC_GLITCH
+ init_Ires(screen.xmc_glitch);
+ init_Ires(screen.xmc_attributes);
+ init_Bres(screen.xmc_inline);
+ init_Bres(screen.move_sgr_ok);
+#endif
+#if OPT_BLINK_CURS
+ init_Bres(screen.cursor_blink);
+ init_Ires(screen.blink_on);
+ init_Ires(screen.blink_off);
+ TScreenOf(wnew)->cursor_blink_res = TScreenOf(wnew)->cursor_blink;
+#endif
+ init_Bres(screen.cursor_underline);
+#if OPT_BLINK_TEXT
+ init_Ires(screen.blink_as_bold);
+#endif
+ init_Ires(screen.border);
+ init_Bres(screen.jumpscroll);
+ init_Bres(screen.fastscroll);
+ init_Bres(screen.old_fkeys);
+ init_Bres(screen.delete_is_del);
+ wnew->keyboard.type = TScreenOf(wnew)->old_fkeys
+ ? keyboardIsLegacy
+ : keyboardIsDefault;
+#ifdef ALLOWLOGGING
+ init_Bres(misc.logInhibit);
+ init_Bres(misc.log_on);
+ init_Sres(screen.logfile);
+#endif
+ init_Bres(screen.bellIsUrgent);
+ init_Bres(screen.bellOnReset);
+ init_Bres(screen.marginbell);
+ init_Bres(screen.multiscroll);
+ init_Ires(screen.nmarginbell);
+ init_Ires(screen.savelines);
+ init_Ires(screen.scrollBarBorder);
+ init_Ires(screen.scrolllines);
+ init_Bres(screen.scrollttyoutput);
+ init_Bres(screen.scrollkey);
+
+ init_Dres(screen.scale_height);
+ if (TScreenOf(wnew)->scale_height < 0.9)
+ TScreenOf(wnew)->scale_height = (float) 0.9;
+ if (TScreenOf(wnew)->scale_height > 1.5)
+ TScreenOf(wnew)->scale_height = (float) 1.5;
+
+ init_Bres(misc.autoWrap);
+ init_Bres(misc.login_shell);
+ init_Bres(misc.reverseWrap);
+ init_Bres(misc.scrollbar);
+ init_Sres(misc.geo_metry);
+ init_Sres(misc.T_geometry);
+
+ init_Sres(screen.term_id);
+ for (s = TScreenOf(request)->term_id; *s; s++) {
+ if (!isalpha(CharOf(*s)))
+ break;
+ }
+ TScreenOf(wnew)->terminal_id = atoi(s);
+ if (TScreenOf(wnew)->terminal_id < MIN_DECID)
+ TScreenOf(wnew)->terminal_id = MIN_DECID;
+ if (TScreenOf(wnew)->terminal_id > MAX_DECID)
+ TScreenOf(wnew)->terminal_id = MAX_DECID;
+ TRACE(("term_id '%s' -> terminal_id %d\n",
+ TScreenOf(wnew)->term_id,
+ TScreenOf(wnew)->terminal_id));
+
+ TScreenOf(wnew)->vtXX_level = (TScreenOf(wnew)->terminal_id / 100);
+
+ init_Ires(screen.title_modes);
+ init_Bres(screen.visualbell);
+ init_Bres(screen.flash_line);
+ init_Ires(screen.visualBellDelay);
+ init_Bres(screen.poponbell);
+ init_Ires(misc.limit_resize);
+
+#if OPT_NUM_LOCK
+ init_Bres(misc.real_NumLock);
+ init_Bres(misc.alwaysUseMods);
+ wnew->misc.num_lock = 0;
+ wnew->misc.alt_mods = 0;
+ wnew->misc.meta_mods = 0;
+ wnew->misc.other_mods = 0;
+#endif
+
+#if OPT_INPUT_METHOD
+ init_Bres(misc.open_im);
+ init_Ires(misc.retry_im);
+ init_Sres(misc.f_x);
+ init_Sres(misc.input_method);
+ init_Sres(misc.preedit_type);
+#endif
+
+#if OPT_SHIFT_FONTS
+ init_Bres(misc.shift_fonts);
+#endif
+#if OPT_SUNPC_KBD
+ init_Ires(misc.ctrl_fkeys);
+#endif
+#if OPT_TEK4014
+ TEK4014_SHOWN(wnew) = False; /* not a resource... */
+ init_Bres(misc.tekInhibit);
+ init_Bres(misc.tekSmall);
+ init_Bres(misc.TekEmu);
+#endif
+#if OPT_TCAP_QUERY
+ TScreenOf(wnew)->tc_query_code = -1;
+#endif
+ wnew->misc.re_verse0 = request->misc.re_verse;
+ init_Bres(misc.re_verse);
+ init_Ires(screen.multiClickTime);
+ init_Ires(screen.bellSuppressTime);
+ init_Sres(screen.charClass);
+
+ init_Bres(screen.always_highlight);
+ init_Bres(screen.brokenSelections);
+ init_Bres(screen.cutNewline);
+ init_Bres(screen.cutToBeginningOfLine);
+ init_Bres(screen.highlight_selection);
+ init_Bres(screen.show_wrap_marks);
+ init_Bres(screen.i18nSelections);
+ init_Bres(screen.keepSelection);
+ init_Bres(screen.selectToClipboard);
+ init_Bres(screen.trim_selection);
+
+ TScreenOf(wnew)->pointer_cursor = TScreenOf(request)->pointer_cursor;
+ init_Ires(screen.pointer_mode);
+
+ init_Sres(screen.answer_back);
+
+ init_Sres(SPS.printer_command);
+ init_Bres(SPS.printer_autoclose);
+ init_Bres(SPS.printer_extent);
+ init_Bres(SPS.printer_formfeed);
+ init_Bres(SPS.printer_newline);
+ init_Ires(SPS.printer_controlmode);
+#if OPT_PRINT_COLORS
+ init_Ires(SPS.print_attributes);
+#endif
+
+ init_Sres(screen.keyboard_dialect);
+
+ init_Bres(screen.input_eight_bits);
+ init_Bres(screen.output_eight_bits);
+ init_Bres(screen.control_eight_bits);
+ init_Bres(screen.backarrow_key);
+ init_Bres(screen.alt_is_not_meta);
+ init_Bres(screen.alt_sends_esc);
+ init_Bres(screen.meta_sends_esc);
+
+ init_Bres(screen.allowSendEvent0);
+ init_Bres(screen.allowColorOp0);
+ init_Bres(screen.allowFontOp0);
+ init_Bres(screen.allowTcapOp0);
+ init_Bres(screen.allowTitleOp0);
+ init_Bres(screen.allowWindowOp0);
+
+#if OPT_SCROLL_LOCK
+ init_Bres(screen.allowScrollLock0);
+#endif
+
+ init_Sres(screen.disallowedColorOps);
+
+ set_flags_from_list(TScreenOf(wnew)->disallow_color_ops,
+ TScreenOf(wnew)->disallowedColorOps,
+ tblColorOps,
+ ecLAST);
+
+ init_Sres(screen.disallowedFontOps);
+
+ set_flags_from_list(TScreenOf(wnew)->disallow_font_ops,
+ TScreenOf(wnew)->disallowedFontOps,
+ tblFontOps,
+ efLAST);
+
+ init_Sres(screen.disallowedTcapOps);
+
+ set_flags_from_list(TScreenOf(wnew)->disallow_tcap_ops,
+ TScreenOf(wnew)->disallowedTcapOps,
+ tblTcapOps,
+ etLAST);
+
+ init_Sres(screen.disallowedWinOps);
+
+ set_flags_from_list(TScreenOf(wnew)->disallow_win_ops,
+ TScreenOf(wnew)->disallowedWinOps,
+ tblWindowOps,
+ ewLAST);
+
+ init_Sres(screen.default_string);
+ init_Sres(screen.eightbit_select_types);
+#if OPT_WIDE_CHARS
+ init_Sres(screen.utf8_select_types);
+#endif
+
+ /* make a copy so that editres cannot change the resource after startup */
+ TScreenOf(wnew)->allowSendEvents = TScreenOf(wnew)->allowSendEvent0;
+ TScreenOf(wnew)->allowColorOps = TScreenOf(wnew)->allowColorOp0;
+ TScreenOf(wnew)->allowFontOps = TScreenOf(wnew)->allowFontOp0;
+ TScreenOf(wnew)->allowTcapOps = TScreenOf(wnew)->allowTcapOp0;
+ TScreenOf(wnew)->allowTitleOps = TScreenOf(wnew)->allowTitleOp0;
+ TScreenOf(wnew)->allowWindowOps = TScreenOf(wnew)->allowWindowOp0;
+
+#if OPT_SCROLL_LOCK
+ TScreenOf(wnew)->allowScrollLock = TScreenOf(wnew)->allowScrollLock0;
+#endif
+
+ init_Bres(screen.quiet_grab);
+
+#ifndef NO_ACTIVE_ICON
+ init_Sres(screen.icon_fontname);
+ TScreenOf(wnew)->fnt_icon.fs = XLoadQueryFont(TScreenOf(wnew)->display,
+ TScreenOf(wnew)->icon_fontname);
+ TRACE(("iconFont '%s' %sloaded successfully\n",
+ TScreenOf(wnew)->icon_fontname,
+ TScreenOf(wnew)->fnt_icon.fs ? "" : "NOT "));
+ init_Bres(misc.active_icon);
+ init_Ires(misc.icon_border_width);
+ wnew->misc.icon_border_pixel = request->misc.icon_border_pixel;
+#endif /* NO_ACTIVE_ICON */
+
+ init_Bres(misc.signalInhibit);
+ init_Bres(misc.titeInhibit);
+ init_Bres(misc.tiXtraScroll);
+ init_Bres(misc.dynamicColors);
+ for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) {
+ init_Sres2(screen.MenuFontName, i);
+ }
+ init_Ires(misc.fontWarnings);
+#define DefaultFontNames TScreenOf(wnew)->menu_font_names[fontMenu_default]
+ init_Sres(misc.default_font.f_n);
+ init_Sres(misc.default_font.f_b);
+ DefaultFontNames[fNorm] = x_strdup(wnew->misc.default_font.f_n);
+ DefaultFontNames[fBold] = x_strdup(wnew->misc.default_font.f_b);
+#if OPT_WIDE_CHARS
+ init_Sres(misc.default_font.f_w);
+ init_Sres(misc.default_font.f_wb);
+ DefaultFontNames[fWide] = x_strdup(wnew->misc.default_font.f_w);
+ DefaultFontNames[fWBold] = x_strdup(wnew->misc.default_font.f_wb);
+#endif
+ TScreenOf(wnew)->MenuFontName(fontMenu_fontescape) = NULL;
+ TScreenOf(wnew)->MenuFontName(fontMenu_fontsel) = NULL;
+
+ TScreenOf(wnew)->menu_font_number = fontMenu_default;
+ init_Sres(screen.initial_font);
+ if (TScreenOf(wnew)->initial_font != 0) {
+ int result = xtermGetFont(TScreenOf(wnew)->initial_font);
+ if (result >= 0)
+ TScreenOf(wnew)->menu_font_number = result;
+ }
+#if OPT_BROKEN_OSC
+ init_Bres(screen.brokenLinuxOSC);
+#endif
+
+#if OPT_BROKEN_ST
+ init_Bres(screen.brokenStringTerm);
+#endif
+
+#if OPT_C1_PRINT
+ init_Bres(screen.c1_printable);
+#endif
+
+#if OPT_CLIP_BOLD
+ init_Bres(screen.use_clipping);
+#endif
+
+#if OPT_DEC_CHRSET
+ init_Bres(screen.font_doublesize);
+ init_Ires(screen.cache_doublesize);
+ if (TScreenOf(wnew)->cache_doublesize > NUM_CHRSET)
+ TScreenOf(wnew)->cache_doublesize = NUM_CHRSET;
+ if (TScreenOf(wnew)->cache_doublesize == 0)
+ TScreenOf(wnew)->font_doublesize = False;
+ TRACE(("Doublesize%s enabled, up to %d fonts\n",
+ TScreenOf(wnew)->font_doublesize ? "" : " not",
+ TScreenOf(wnew)->cache_doublesize));
+#endif
+
+#if OPT_ISO_COLORS
+ init_Ires(screen.veryBoldColors);
+ init_Bres(screen.boldColors);
+ init_Bres(screen.colorAttrMode);
+ init_Bres(screen.colorBDMode);
+ init_Bres(screen.colorBLMode);
+ init_Bres(screen.colorMode);
+ init_Bres(screen.colorULMode);
+ init_Bres(screen.italicULMode);
+ init_Bres(screen.colorRVMode);
+
+#if OPT_COLOR_RES2
+ TRACE(("...will fake resources for color%d to color%d\n",
+ MIN_ANSI_COLORS,
+ NUM_ANSI_COLORS - 1));
+#endif
+ for (i = 0, color_ok = False; i < MAXCOLORS; i++) {
+
+#if OPT_COLOR_RES2
+ /*
+ * Xt has a hardcoded limit on the maximum number of resources that can
+ * be used in a widget. If we configure both luit (which implies
+ * wide-characters) and 256-colors, it goes over that limit. Most
+ * people would not need a resource-file with 256-colors; the default
+ * values in our table are sufficient. In that case, fake the resource
+ * setting by copying the default value from the table. The #define's
+ * can be overridden to make these true resources.
+ */
+ if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) {
+ TScreenOf(wnew)->Acolors[i].resource =
+ x_strtrim(fake_resources[i - MIN_ANSI_COLORS].default_addr);
+ if (TScreenOf(wnew)->Acolors[i].resource == 0)
+ TScreenOf(wnew)->Acolors[i].resource = XtDefaultForeground;
+ } else
+#endif /* OPT_COLOR_RES2 */
+ {
+ TScreenOf(wnew)->Acolors[i] = TScreenOf(request)->Acolors[i];
+ TScreenOf(wnew)->Acolors[i].resource =
+ x_strtrim(TScreenOf(wnew)->Acolors[i].resource);
+ }
+
+#if OPT_COLOR_RES
+ TRACE(("Acolors[%d] = %s\n", i, TScreenOf(wnew)->Acolors[i].resource));
+ TScreenOf(wnew)->Acolors[i].mode = False;
+ if (DftFg(Acolors[i])) {
+ TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_FG);
+ TScreenOf(wnew)->Acolors[i].mode = True;
+ } else if (DftBg(Acolors[i])) {
+ TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_BG);
+ TScreenOf(wnew)->Acolors[i].mode = True;
+ } else {
+ color_ok = True;
+ }
+#else
+ TRACE(("Acolors[%d] = %#lx\n", i, TScreenOf(request)->Acolors[i]));
+ if (TScreenOf(wnew)->Acolors[i] != wnew->dft_foreground &&
+ TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_FG) &&
+ TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_BG))
+ color_ok = True;
+#endif
+ }
+
+ /*
+ * Check if we're trying to use color in a monochrome screen. Disable
+ * color in that case, since that would make ANSI colors unusable. A 4-bit
+ * or 8-bit display is usable, so we do not have to check for anything more
+ * specific.
+ */
+ if (color_ok) {
+ Display *display = TScreenOf(wnew)->display;
+ XVisualInfo myTemplate, *visInfoPtr;
+ int numFound;
+
+ myTemplate.visualid = XVisualIDFromVisual(DefaultVisual(display,
+ XDefaultScreen(display)));
+ visInfoPtr = XGetVisualInfo(display, (long) VisualIDMask,
+ &myTemplate, &numFound);
+ if (visInfoPtr == 0
+ || numFound == 0
+ || visInfoPtr->depth <= 1) {
+ TRACE(("disabling color since screen is monochrome\n"));
+ color_ok = False;
+ } else {
+ XFree(visInfoPtr);
+ }
+ }
+
+ /* If none of the colors are anything other than the foreground or
+ * background, we'll assume this isn't color, no matter what the colorMode
+ * resource says. (There doesn't seem to be any good way to determine if
+ * the resource lookup failed versus the user having misconfigured this).
+ */
+ if (!color_ok) {
+ TScreenOf(wnew)->colorMode = False;
+ TRACE(("All colors are foreground or background: disable colorMode\n"));
+ }
+ wnew->sgr_foreground = -1;
+ wnew->sgr_background = -1;
+ wnew->sgr_extended = False;
+#endif /* OPT_ISO_COLORS */
+
+ /*
+ * Decode the resources that control the behavior on multiple mouse clicks.
+ * A single click is always bound to normal character selection, but the
+ * other flavors can be changed.
+ */
+ for (i = 0; i < NSELECTUNITS; ++i) {
+ int ck = (i + 1);
+ TScreenOf(wnew)->maxClicks = ck;
+ if (i == Select_CHAR)
+ TScreenOf(wnew)->selectMap[i] = Select_CHAR;
+ else if (TScreenOf(request)->onClick[i] != 0)
+ ParseOnClicks(wnew, request, (unsigned) i);
+ else if (i <= Select_LINE)
+ TScreenOf(wnew)->selectMap[i] = (SelectUnit) i;
+ else
+ break;
+ TRACE(("on%dClicks %s=%d\n", ck,
+ NonNull(TScreenOf(request)->onClick[i]),
+ TScreenOf(wnew)->selectMap[i]));
+ if (TScreenOf(wnew)->selectMap[i] == NSELECTUNITS)
+ break;
+ }
+ TRACE(("maxClicks %d\n", TScreenOf(wnew)->maxClicks));
+
+ init_Tres(MOUSE_FG);
+ init_Tres(MOUSE_BG);
+ init_Tres(TEXT_CURSOR);
+#if OPT_HIGHLIGHT_COLOR
+ init_Tres(HIGHLIGHT_BG);
+ init_Tres(HIGHLIGHT_FG);
+ init_Bres(screen.hilite_reverse);
+ init_Bres(screen.hilite_color);
+ if (TScreenOf(wnew)->hilite_color == Maybe) {
+ TScreenOf(wnew)->hilite_color = False;
+#if OPT_COLOR_RES
+ /*
+ * If the highlight text/background are both set, and if they are
+ * not equal to either the text/background or background/text, then
+ * set the highlightColorMode automatically.
+ */
+ if (!DftFg(Tcolors[HIGHLIGHT_BG])
+ && !DftBg(Tcolors[HIGHLIGHT_FG])
+ && !TxtFg(Tcolors[HIGHLIGHT_BG])
+ && !TxtBg(Tcolors[HIGHLIGHT_FG])
+ && !TxtBg(Tcolors[HIGHLIGHT_BG])
+ && !TxtFg(Tcolors[HIGHLIGHT_FG])) {
+ TRACE(("...setting hilite_color automatically\n"));
+ TScreenOf(wnew)->hilite_color = True;
+ }
+#endif
+ }
+#endif
+
+#if OPT_TEK4014
+ /*
+ * The Tek4014 window has no separate resources for foreground, background
+ * and cursor color. Since xterm always creates the vt100 widget first, we
+ * can set the Tektronix colors here. That lets us use escape sequences to
+ * set its dynamic colors and get consistent behavior whether or not the
+ * window is displayed.
+ */
+ TScreenOf(wnew)->Tcolors[TEK_BG] = TScreenOf(wnew)->Tcolors[TEXT_BG];
+ TScreenOf(wnew)->Tcolors[TEK_FG] = TScreenOf(wnew)->Tcolors[TEXT_FG];
+ TScreenOf(wnew)->Tcolors[TEK_CURSOR] = TScreenOf(wnew)->Tcolors[TEXT_CURSOR];
+#endif
+
+#ifdef SCROLLBAR_RIGHT
+ init_Bres(misc.useRight);
+#endif
+
+#if OPT_RENDERFONT
+ for (i = 0; i <= fontMenu_lastBuiltin; ++i) {
+ init_Dres2(misc.face_size, i);
+ }
+ init_Sres(misc.face_name);
+ init_Sres(misc.face_wide_name);
+ init_Sres(misc.render_font_s);
+ wnew->misc.render_font =
+ (Boolean) extendedBoolean(wnew->misc.render_font_s,
+ tblRenderFont, erLast);
+ if (wnew->misc.render_font == erDefault) {
+ if (IsEmpty(wnew->misc.face_name)) {
+ free(wnew->misc.face_name);
+ wnew->misc.face_name = x_strdup(DEFFACENAME_AUTO);
+ TRACE(("will allow runtime switch to render_font using \"%s\"\n",
+ wnew->misc.face_name));
+ } else {
+ wnew->misc.render_font = erTrue;
+ TRACE(("initially using TrueType font\n"));
+ }
+ }
+ /* minor tweak to make debug traces consistent: */
+ if (wnew->misc.render_font) {
+ if (IsEmpty(wnew->misc.face_name)) {
+ wnew->misc.render_font = False;
+ TRACE(("reset render_font since there is no face_name\n"));
+ }
+ }
+#endif
+
+#if OPT_WIDE_CHARS
+ /* setup data for next call */
+ request->screen.utf8_mode =
+ extendedBoolean(request->screen.utf8_mode_s, tblUtf8Mode, uLast);
+ request->screen.utf8_fonts =
+ extendedBoolean(request->screen.utf8_fonts_s, tblUtf8Mode, uLast);
+
+ VTInitialize_locale(request);
+ init_Bres(screen.normalized_c);
+ init_Bres(screen.utf8_latin1);
+ init_Bres(screen.utf8_title);
+
+#if OPT_LUIT_PROG
+ init_Bres(misc.callfilter);
+ init_Bres(misc.use_encoding);
+ init_Sres(misc.locale_str);
+ init_Sres(misc.localefilter);
+#endif
+
+ init_Ires(screen.utf8_inparse);
+ init_Ires(screen.utf8_mode);
+ init_Ires(screen.utf8_fonts);
+ init_Ires(screen.max_combining);
+
+ if (TScreenOf(wnew)->max_combining < 0) {
+ TScreenOf(wnew)->max_combining = 0;
+ }
+ if (TScreenOf(wnew)->max_combining > 5) {
+ TScreenOf(wnew)->max_combining = 5;
+ }
+
+ init_Bres(screen.vt100_graphics);
+ init_Bres(screen.wide_chars);
+ init_Bres(misc.mk_width);
+ init_Bres(misc.cjk_width);
+
+ init_Ires(misc.mk_samplesize);
+ init_Ires(misc.mk_samplepass);
+
+ if (wnew->misc.mk_samplesize > 0xffff)
+ wnew->misc.mk_samplesize = 0xffff;
+ if (wnew->misc.mk_samplesize < 0)
+ wnew->misc.mk_samplesize = 0;
+
+ if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize)
+ wnew->misc.mk_samplepass = wnew->misc.mk_samplesize;
+ if (wnew->misc.mk_samplepass < 0)
+ wnew->misc.mk_samplepass = 0;
+
+ if (TScreenOf(request)->utf8_mode) {
+ TRACE(("setting wide_chars on\n"));
+ TScreenOf(wnew)->wide_chars = True;
+ } else {
+ TRACE(("setting utf8_mode to 0\n"));
+ TScreenOf(wnew)->utf8_mode = uFalse;
+ }
+ TRACE(("initialized UTF-8 mode to %d\n", TScreenOf(wnew)->utf8_mode));
+
+#if OPT_MINI_LUIT
+ if (TScreenOf(request)->latin9_mode) {
+ TScreenOf(wnew)->latin9_mode = True;
+ }
+ if (TScreenOf(request)->unicode_font) {
+ TScreenOf(wnew)->unicode_font = True;
+ }
+ TRACE(("initialized Latin9 mode to %d\n", TScreenOf(wnew)->latin9_mode));
+ TRACE(("initialized unicode_font to %d\n", TScreenOf(wnew)->unicode_font));
+#endif
+
+ decode_wcwidth(wnew);
+ xtermSaveVTFonts(wnew);
+#endif /* OPT_WIDE_CHARS */
+
+ init_Sres(screen.eight_bit_meta_s);
+ wnew->screen.eight_bit_meta =
+ extendedBoolean(request->screen.eight_bit_meta_s, tbl8BitMeta, uLast);
+ if (wnew->screen.eight_bit_meta == ebLocale) {
+#if OPT_WIDE_CHARS
+ if (xtermEnvUTF8()) {
+ wnew->screen.eight_bit_meta = ebFalse;
+ TRACE(("...eightBitMeta is false due to locale\n"));
+ } else
+#endif /* OPT_WIDE_CHARS */
+ {
+ wnew->screen.eight_bit_meta = ebTrue;
+ TRACE(("...eightBitMeta is true due to locale\n"));
+ }
+ }
+
+ init_Bres(screen.always_bold_mode);
+ init_Bres(screen.bold_mode);
+ init_Bres(screen.underline);
+
+ wnew->cur_foreground = 0;
+ wnew->cur_background = 0;
+
+ wnew->keyboard.flags = MODE_SRM;
+ if (TScreenOf(wnew)->backarrow_key)
+ wnew->keyboard.flags |= MODE_DECBKM;
+ TRACE(("initialized DECBKM %s\n",
+ BtoS(wnew->keyboard.flags & MODE_DECBKM)));
+
+ /* look for focus related events on the shell, because we need
+ * to care about the shell's border being part of our focus.
+ */
+ TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent));
+ XtAddEventHandler(my_parent, EnterWindowMask, False,
+ HandleEnterWindow, (Opaque) NULL);
+ XtAddEventHandler(my_parent, LeaveWindowMask, False,
+ HandleLeaveWindow, (Opaque) NULL);
+ XtAddEventHandler(my_parent, FocusChangeMask, False,
+ HandleFocusChange, (Opaque) NULL);
+ XtAddEventHandler((Widget) wnew, 0L, True,
+ VTNonMaskableEvent, (Opaque) NULL);
+ XtAddEventHandler((Widget) wnew, PropertyChangeMask, False,
+ HandleBellPropertyChange, (Opaque) NULL);
+
+#if HANDLE_STRUCT_NOTIFY
+#if OPT_TOOLBAR
+ wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar);
+ init_Ires(VT100_TB_INFO(menu_height));
+#else
+ /* Flag icon name with "***" on window output when iconified.
+ * Put in a handler that will tell us when we get Map/Unmap events.
+ */
+ if (resource.zIconBeep)
+#endif
+ XtAddEventHandler(my_parent, StructureNotifyMask, False,
+ HandleStructNotify, (Opaque) 0);
+#endif /* HANDLE_STRUCT_NOTIFY */
+
+ TScreenOf(wnew)->bellInProgress = False;
+
+ set_character_class(TScreenOf(wnew)->charClass);
+
+ /* create it, but don't realize it */
+ ScrollBarOn(wnew, True);
+
+ /* make sure that the resize gravity acceptable */
+ if (!GravityIsNorthWest(wnew) &&
+ !GravityIsSouthWest(wnew)) {
+ char value[80];
+ String temp[2];
+ Cardinal nparams = 1;
+
+ sprintf(value, "%d", wnew->misc.resizeGravity);
+ temp[0] = value;
+ temp[1] = 0;
+ XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError",
+ "unsupported resizeGravity resource value (%s)",
+ temp, &nparams);
+ wnew->misc.resizeGravity = SouthWestGravity;
+ }
+#ifndef NO_ACTIVE_ICON
+ TScreenOf(wnew)->whichVwin = &TScreenOf(wnew)->fullVwin;
+#endif /* NO_ACTIVE_ICON */
+
+ if (TScreenOf(wnew)->savelines < 0)
+ TScreenOf(wnew)->savelines = 0;
+
+ init_Bres(screen.awaitInput);
+
+ wnew->flags = 0;
+ if (!TScreenOf(wnew)->jumpscroll)
+ wnew->flags |= SMOOTHSCROLL;
+ if (wnew->misc.reverseWrap)
+ wnew->flags |= REVERSEWRAP;
+ if (wnew->misc.autoWrap)
+ wnew->flags |= WRAPAROUND;
+ if (wnew->misc.re_verse != wnew->misc.re_verse0)
+ wnew->flags |= REVERSE_VIDEO;
+ if (TScreenOf(wnew)->c132)
+ wnew->flags |= IN132COLUMNS;
+
+ wnew->initflags = wnew->flags;
+
+#if OPT_MOD_FKEYS
+ init_Ires(keyboard.modify_1st.allow_keys);
+ init_Ires(keyboard.modify_1st.cursor_keys);
+ init_Ires(keyboard.modify_1st.function_keys);
+ init_Ires(keyboard.modify_1st.keypad_keys);
+ init_Ires(keyboard.modify_1st.other_keys);
+ init_Ires(keyboard.modify_1st.string_keys);
+ init_Ires(keyboard.format_keys);
+ wnew->keyboard.modify_now = wnew->keyboard.modify_1st;
+#endif
+
+ init_Ires(misc.appcursorDefault);
+ if (wnew->misc.appcursorDefault)
+ wnew->keyboard.flags |= MODE_DECCKM;
+
+ init_Ires(misc.appkeypadDefault);
+ if (wnew->misc.appkeypadDefault)
+ wnew->keyboard.flags |= MODE_DECKPAM;
+
+ initLineData(wnew);
+ return;
+}
+
+void
+releaseCursorGCs(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ VTwin *win = WhichVWin(screen);
+ int n;
+
+ for_each_curs_gc(n) {
+ freeCgs(xw, win, (CgsEnum) n);
+ }
+}
+
+void
+releaseWindowGCs(XtermWidget xw, VTwin * win)
+{
+ int n;
+
+ for_each_text_gc(n) {
+ freeCgs(xw, win, (CgsEnum) n);
+ }
+}
+
+#define TRACE_FREE_LEAK(name) \
+ if (name) { \
+ free((void *) name); \
+ TRACE(("freed " #name ": %p\n", (const void *) name)); \
+ name = 0; \
+ }
+
+#define FREE_LEAK(name) \
+ if (name) { \
+ free((void *) name); \
+ name = 0; \
+ }
+
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+static void
+cleanupInputMethod(XtermWidget xw)
+{
+ TInput *input = lookupTInput(xw, (Widget) xw);
+
+ if (input && input->xim) {
+ XCloseIM(input->xim);
+ input->xim = 0;
+ TRACE(("freed screen->xim\n"));
+ }
+}
+#endif
+
+static void
+VTDestroy(Widget w GCC_UNUSED)
+{
+#ifdef NO_LEAKS
+ XtermWidget xw = (XtermWidget) w;
+ TScreen *screen = TScreenOf(xw);
+ Cardinal n;
+
+ StopBlinking(screen);
+
+ if (screen->scrollWidget) {
+ XtUninstallTranslations(screen->scrollWidget);
+ XtDestroyWidget(screen->scrollWidget);
+ }
+#if OPT_FIFO_LINES
+ while (screen->saved_fifo-- > 0) {
+ deleteScrollback(screen, 0);
+ }
+#endif
+ while (screen->save_title != 0) {
+ SaveTitle *last = screen->save_title;
+ screen->save_title = last->next;
+ free(last->iconName);
+ free(last->windowName);
+ free(last);
+ }
+#if OPT_ISO_COLORS
+ TRACE_FREE_LEAK(screen->cmap_data);
+ for (n = 0; n < MAXCOLORS; n++) {
+ TRACE_FREE_LEAK(screen->Acolors[n].resource);
+ }
+#endif
+#if OPT_COLOR_RES
+ for (n = 0; n < NCOLORS; n++) {
+ switch (n) {
+#if OPT_TEK4014
+ case TEK_BG:
+ case TEK_FG:
+ case TEK_CURSOR:
+ break;
+#endif
+ default:
+ TRACE_FREE_LEAK(screen->Tcolors[n].resource);
+ break;
+ }
+ }
+#endif
+ TRACE_FREE_LEAK(screen->save_ptr);
+ TRACE_FREE_LEAK(screen->saveBuf_data);
+ TRACE_FREE_LEAK(screen->saveBuf_index);
+ for (n = 0; n < 2; ++n) {
+ TRACE_FREE_LEAK(screen->editBuf_data[n]);
+ TRACE_FREE_LEAK(screen->editBuf_index[n]);
+ }
+ TRACE_FREE_LEAK(screen->keyboard_dialect);
+ TRACE_FREE_LEAK(screen->term_id);
+#if OPT_WIDE_CHARS
+#if OPT_LUIT_PROG
+ TRACE_FREE_LEAK(xw->misc.locale_str);
+ TRACE_FREE_LEAK(xw->misc.localefilter);
+#endif
+#endif
+ TRACE_FREE_LEAK(xw->misc.T_geometry);
+ TRACE_FREE_LEAK(xw->misc.geo_metry);
+ TRACE_FREE_LEAK(xw->screen.term_id);
+#if OPT_INPUT_METHOD
+ cleanupInputMethod(xw);
+ TRACE_FREE_LEAK(xw->misc.f_x);
+ TRACE_FREE_LEAK(xw->misc.input_method);
+ TRACE_FREE_LEAK(xw->misc.preedit_type);
+#endif
+ releaseCursorGCs(xw);
+ releaseWindowGCs(xw, &(screen->fullVwin));
+#ifndef NO_ACTIVE_ICON
+ releaseWindowGCs(xw, &(screen->iconVwin));
+#endif
+ XtUninstallTranslations((Widget) xw);
+#if OPT_TOOLBAR
+ XtUninstallTranslations((Widget) XtParent(xw));
+#endif
+ XtUninstallTranslations((Widget) SHELL_OF(xw));
+
+ if (screen->hidden_cursor)
+ XFreeCursor(screen->display, screen->hidden_cursor);
+
+ xtermCloseFonts(xw, screen->fnts);
+ noleaks_cachedCgs(xw);
+
+ TRACE_FREE_LEAK(screen->selection_targets_8bit);
+#if OPT_SELECT_REGEX
+ for (n = 0; n < NSELECTUNITS; ++n) {
+ if (screen->selectMap[n] == Select_REGEX) {
+ TRACE_FREE_LEAK(screen->selectExpr[n]);
+ }
+ }
+#endif
+
+#if OPT_RENDERFONT
+ for (n = 0; n < NMENUFONTS; ++n) {
+ xtermCloseXft(screen, &(screen->renderFontNorm[n]));
+ xtermCloseXft(screen, &(screen->renderFontBold[n]));
+ xtermCloseXft(screen, &(screen->renderFontItal[n]));
+#if OPT_RENDERWIDE
+ xtermCloseXft(screen, &(screen->renderWideNorm[n]));
+ xtermCloseXft(screen, &(screen->renderWideBold[n]));
+ xtermCloseXft(screen, &(screen->renderWideItal[n]));
+#endif
+ }
+#endif
+
+ /* free things allocated via init_Sres or Init_Sres2 */
+#ifndef NO_ACTIVE_ICON
+ TRACE_FREE_LEAK(screen->icon_fontname);
+#endif
+#ifdef ALLOWLOGGING
+ TRACE_FREE_LEAK(screen->logfile);
+#endif
+ TRACE_FREE_LEAK(screen->eight_bit_meta_s);
+ TRACE_FREE_LEAK(screen->term_id);
+ TRACE_FREE_LEAK(screen->charClass);
+ TRACE_FREE_LEAK(screen->answer_back);
+ TRACE_FREE_LEAK(screen->printer_state.printer_command);
+ TRACE_FREE_LEAK(screen->keyboard_dialect);
+ TRACE_FREE_LEAK(screen->disallowedColorOps);
+ TRACE_FREE_LEAK(screen->disallowedFontOps);
+ TRACE_FREE_LEAK(screen->disallowedTcapOps);
+ TRACE_FREE_LEAK(screen->disallowedWinOps);
+ TRACE_FREE_LEAK(screen->default_string);
+ TRACE_FREE_LEAK(screen->eightbit_select_types);
+#if OPT_WIDE_CHARS
+ TRACE_FREE_LEAK(screen->utf8_select_types);
+#endif
+#if 0
+ for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) {
+ TRACE_FREE_LEAK(screen->MenuFontName(n));
+ }
+#endif
+ TRACE_FREE_LEAK(screen->initial_font);
+#if OPT_LUIT_PROG
+ TRACE_FREE_LEAK(xw->misc.locale_str);
+ TRACE_FREE_LEAK(xw->misc.localefilter);
+#endif
+#if OPT_RENDERFONT
+ TRACE_FREE_LEAK(xw->misc.face_name);
+ TRACE_FREE_LEAK(xw->misc.face_wide_name);
+ TRACE_FREE_LEAK(xw->misc.render_font_s);
+#endif
+
+#if OPT_SELECT_REGEX
+ for (n = 0; n < NSELECTUNITS; ++n) {
+ FREE_LEAK(screen->selectExpr[n]);
+ }
+#endif
+
+ if (screen->selection_atoms)
+ XtFree((char *) (screen->selection_atoms));
+
+ XtFree((char *) (screen->selection_data));
+
+ TRACE_FREE_LEAK(xtermClassRec.core_class.tm_table);
+ TRACE_FREE_LEAK(xw->keyboard.extra_translations);
+ TRACE_FREE_LEAK(xw->keyboard.shell_translations);
+ TRACE_FREE_LEAK(xw->keyboard.xterm_translations);
+
+#if OPT_WIDE_CHARS
+ FreeTypedBuffer(XChar2b);
+ FreeTypedBuffer(char);
+#endif
+#if OPT_RENDERFONT
+#if OPT_RENDERWIDE
+ FreeTypedBuffer(XftCharSpec);
+#else
+ FreeTypedBuffer(XftChar8);
+#endif
+#endif
+
+ TRACE_FREE_LEAK(myState.print_area);
+ TRACE_FREE_LEAK(myState.string_area);
+ memset(&myState, 0, sizeof(myState));
+
+#endif /* defined(NO_LEAKS) */
+}
+
+/*ARGSUSED*/
+static void
+VTRealize(Widget w,
+ XtValueMask * valuemask,
+ XSetWindowAttributes * values)
+{
+ XtermWidget xw = (XtermWidget) w;
+ TScreen *screen = TScreenOf(xw);
+
+ const VTFontNames *myfont;
+ unsigned width, height;
+ int xpos, ypos, pr;
+ Atom pid_atom;
+ int i;
+
+ TRACE(("VTRealize\n"));
+
+ TabReset(xw->tabs);
+
+ if (screen->menu_font_number == fontMenu_default) {
+ myfont = &(xw->misc.default_font);
+ } else {
+ myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number));
+ }
+ memset(screen->fnts, 0, sizeof(screen->fnts));
+
+ if (!xtermLoadFont(xw,
+ myfont,
+ False,
+ screen->menu_font_number)) {
+ if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) {
+ char *use_font = x_strdup(DEFFONT);
+ xtermWarning("unable to open font \"%s\", trying \"%s\"....\n",
+ myfont->f_n, use_font);
+ (void) xtermLoadFont(xw,
+ xtermFontName(use_font),
+ False,
+ screen->menu_font_number);
+ screen->MenuFontName(screen->menu_font_number) = use_font;
+ }
+ }
+
+ /* really screwed if we couldn't open default font */
+ if (!screen->fnts[fNorm].fs) {
+ xtermWarning("unable to locate a suitable font\n");
+ Exit(1);
+ }
+#if OPT_WIDE_CHARS
+ if (screen->utf8_mode) {
+ TRACE(("check if this is a wide font, if not try again\n"));
+ if (xtermLoadWideFonts(xw, False)) {
+ SetVTFont(xw, screen->menu_font_number, True, NULL);
+ /* we will not be able to switch to ISO-8859-1 */
+ if (!screen->mergedVTFonts) {
+ screen->utf8_fonts = uAlways;
+ update_font_utf8_fonts();
+ }
+ }
+ }
+#endif
+
+ /* making cursor */
+ if (!screen->pointer_cursor) {
+ screen->pointer_cursor =
+ make_colored_cursor(XC_xterm,
+ T_COLOR(screen, MOUSE_FG),
+ T_COLOR(screen, MOUSE_BG));
+ } else {
+ recolor_cursor(screen,
+ screen->pointer_cursor,
+ T_COLOR(screen, MOUSE_FG),
+ T_COLOR(screen, MOUSE_BG));
+ }
+
+ /* set defaults */
+ xpos = 1;
+ ypos = 1;
+ width = 80;
+ height = 24;
+
+ TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry)));
+ pr = XParseGeometry(xw->misc.geo_metry, &xpos, &ypos,
+ &width, &height);
+ TRACE(("... position %d,%d size %dx%d\n", ypos, xpos, height, width));
+
+ set_max_col(screen, (int) (width - 1)); /* units in character cells */
+ set_max_row(screen, (int) (height - 1)); /* units in character cells */
+ xtermUpdateFontInfo(xw, False);
+
+ width = screen->fullVwin.fullwidth;
+ height = screen->fullVwin.fullheight;
+
+ TRACE(("... border widget %d parent %d shell %d\n",
+ BorderWidth(xw),
+ BorderWidth(XtParent(xw)),
+ BorderWidth(SHELL_OF(xw))));
+
+ if ((pr & XValue) && (XNegative & pr)) {
+ xpos += (DisplayWidth(screen->display, DefaultScreen(screen->display))
+ - (int) width
+ - (BorderWidth(XtParent(xw)) * 2));
+ }
+ if ((pr & YValue) && (YNegative & pr)) {
+ ypos += (DisplayHeight(screen->display, DefaultScreen(screen->display))
+ - (int) height
+ - (BorderWidth(XtParent(xw)) * 2));
+ }
+
+ /* set up size hints for window manager; min 1 char by 1 char */
+ getXtermSizeHints(xw);
+ xtermSizeHints(xw, (xw->misc.scrollbar
+ ? (screen->scrollWidget->core.width
+ + BorderWidth(screen->scrollWidget))
+ : 0));
+
+ xw->hints.x = xpos;
+ xw->hints.y = ypos;
+#if OPT_MAXIMIZE
+ /* assure single-increment resize for fullscreen */
+ if (term->screen.fullscreen) {
+ xw->hints.width_inc = 1;
+ xw->hints.height_inc = 1;
+ }
+#endif
+ if ((XValue & pr) || (YValue & pr)) {
+ xw->hints.flags |= USSize | USPosition;
+ xw->hints.flags |= PWinGravity;
+ switch (pr & (XNegative | YNegative)) {
+ case 0:
+ xw->hints.win_gravity = NorthWestGravity;
+ break;
+ case XNegative:
+ xw->hints.win_gravity = NorthEastGravity;
+ break;
+ case YNegative:
+ xw->hints.win_gravity = SouthWestGravity;
+ break;
+ default:
+ xw->hints.win_gravity = SouthEastGravity;
+ break;
+ }
+ } else {
+ /* set a default size, but do *not* set position */
+ xw->hints.flags |= PSize;
+ }
+ xw->hints.height = xw->hints.base_height
+ + xw->hints.height_inc * MaxRows(screen);
+ xw->hints.width = xw->hints.base_width
+ + xw->hints.width_inc * MaxCols(screen);
+
+ if ((WidthValue & pr) || (HeightValue & pr))
+ xw->hints.flags |= USSize;
+ else
+ xw->hints.flags |= PSize;
+
+ /*
+ * Note that the size-hints are for the shell, while the resize-request
+ * is for the vt100 widget. They are not the same size.
+ */
+ (void) REQ_RESIZE((Widget) xw,
+ (Dimension) width, (Dimension) height,
+ &xw->core.width, &xw->core.height);
+
+ /* XXX This is bogus. We are parsing geometries too late. This
+ * is information that the shell widget ought to have before we get
+ * realized, so that it can do the right thing.
+ */
+ if (xw->hints.flags & USPosition)
+ XMoveWindow(XtDisplay(xw), VShellWindow(xw),
+ xw->hints.x, xw->hints.y);
+
+ TRACE(("%s@%d -- ", __FILE__, __LINE__));
+ TRACE_HINTS(&xw->hints);
+ XSetWMNormalHints(XtDisplay(xw), VShellWindow(xw), &xw->hints);
+ TRACE(("%s@%d -- ", __FILE__, __LINE__));
+ TRACE_WM_HINTS(xw);
+
+ if ((pid_atom = XInternAtom(XtDisplay(xw), "_NET_WM_PID", False)) != None) {
+ /* XChangeProperty format 32 really is "long" */
+ unsigned long pid_l = (unsigned long) getpid();
+ TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l));
+ XChangeProperty(XtDisplay(xw), VShellWindow(xw),
+ pid_atom, XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &pid_l, 1);
+ }
+
+ XFlush(XtDisplay(xw)); /* get it out to window manager */
+
+ /* use ForgetGravity instead of SouthWestGravity because translating
+ the Expose events for ConfigureNotifys is too hard */
+ values->bit_gravity = (GravityIsNorthWest(xw)
+ ? NorthWestGravity
+ : ForgetGravity);
+ screen->fullVwin.window = XtWindow(xw) =
+ XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)),
+ xw->core.x, xw->core.y,
+ xw->core.width, xw->core.height, BorderWidth(xw),
+ (int) xw->core.depth,
+ InputOutput, CopyFromParent,
+ *valuemask | CWBitGravity, values);
+ screen->event_mask = values->event_mask;
+
+#ifndef NO_ACTIVE_ICON
+ /*
+ * Normally, the font-number for icon fonts does not correspond with any of
+ * the menu-selectable fonts. If we cannot load the font given for the
+ * iconFont resource, try with font1 aka "Unreadable".
+ */
+ screen->icon_fontnum = -1;
+ if (screen->fnt_icon.fs == 0) {
+ screen->fnt_icon.fs = XLoadQueryFont(screen->display,
+ screen->MenuFontName(fontMenu_font1));
+ TRACE(("%susing font1 '%s' as iconFont\n",
+ (screen->fnt_icon.fs
+ ? ""
+ : "NOT "),
+ screen->MenuFontName(fontMenu_font1)));
+ }
+#if OPT_RENDERFONT
+ /*
+ * If we still have no result from iconFont resource (perhaps because fonts
+ * are missing) but are using Xft, try to use that instead. We prefer
+ * bitmap fonts in any case, since scaled fonts are usually less readable,
+ * particularly at small sizes.
+ */
+ if (UsingRenderFont(xw)
+ && screen->fnt_icon.fs == 0) {
+ screen->icon_fontnum = fontMenu_default;
+ screen->fnt_icon.fs = screen->fnts[0].fs; /* need for next-if */
+ TRACE(("using TrueType font as iconFont\n"));
+ }
+#endif
+ if (xw->misc.active_icon && screen->fnt_icon.fs) {
+ int iconX = 0, iconY = 0;
+ Widget shell = SHELL_OF(xw);
+ VTwin *win = &(screen->iconVwin);
+ int save_fontnum = screen->menu_font_number;
+
+ TRACE(("Initializing active-icon %d\n", screen->icon_fontnum));
+ screen->menu_font_number = screen->icon_fontnum;
+ XtVaGetValues(shell,
+ XtNiconX, &iconX,
+ XtNiconY, &iconY,
+ (XtPointer) 0);
+ xtermComputeFontInfo(xw, &(screen->iconVwin), screen->fnt_icon.fs, 0);
+ screen->menu_font_number = save_fontnum;
+
+ /* since only one client is permitted to select for Button
+ * events, we have to let the window manager get 'em...
+ */
+ values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask);
+ values->border_pixel = xw->misc.icon_border_pixel;
+
+ screen->iconVwin.window =
+ XCreateWindow(XtDisplay(xw),
+ RootWindowOfScreen(XtScreen(shell)),
+ iconX, iconY,
+ screen->iconVwin.fullwidth,
+ screen->iconVwin.fullheight,
+ xw->misc.icon_border_width,
+ (int) xw->core.depth,
+ InputOutput, CopyFromParent,
+ *valuemask | CWBitGravity | CWBorderPixel,
+ values);
+ XtVaSetValues(shell,
+ XtNiconWindow, screen->iconVwin.window,
+ (XtPointer) 0);
+ XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w);
+
+ setCgsFont(xw, win, gcNorm, &(screen->fnt_icon));
+ setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG));
+ setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG));
+
+ copyCgs(xw, win, gcBold, gcNorm);
+
+ setCgsFont(xw, win, gcNormReverse, &(screen->fnt_icon));
+ setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG));
+ setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG));
+
+ copyCgs(xw, win, gcBoldReverse, gcNormReverse);
+
+#if OPT_TOOLBAR
+ /*
+ * Toolbar is initialized before we get here. Enable the menu item
+ * and set it properly.
+ */
+ SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, True);
+ update_activeicon();
+#endif
+ } else {
+ TRACE(("Disabled active-icon\n"));
+ xw->misc.active_icon = False;
+ }
+#endif /* NO_ACTIVE_ICON */
+
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+ VTInitI18N(xw);
+#endif
+#if OPT_NUM_LOCK
+ VTInitModifiers(xw);
+#if OPT_EXTRA_PASTE
+ if (xw->keyboard.extra_translations) {
+ XtOverrideTranslations((Widget) xw,
+ XtParseTranslationTable(xw->keyboard.extra_translations));
+ }
+#endif
+#endif
+
+ set_cursor_gcs(xw);
+
+ /* Reset variables used by ANSI emulation. */
+
+ resetCharsets(screen);
+
+ XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor);
+
+ set_cur_col(screen, 0);
+ set_cur_row(screen, 0);
+ set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1);
+ set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1);
+ reset_margins(screen);
+
+ memset(screen->sc, 0, sizeof(screen->sc));
+
+ /* Mark screen buffer as unallocated. We wait until the run loop so
+ that the child process does not fork and exec with all the dynamic
+ memory it will never use. If we were to do it here, the
+ swap space for new process would be huge for huge savelines. */
+#if OPT_TEK4014
+ if (!tekWidget) /* if not called after fork */
+#endif
+ {
+ screen->visbuf = NULL;
+ screen->saveBuf_index = NULL;
+ }
+
+ ResetWrap(screen);
+ screen->scrolls = screen->incopy = 0;
+ xtermSetCursorBox(screen);
+
+ screen->savedlines = 0;
+
+ for (i = 0; i < 2; ++i) {
+ screen->whichBuf = !screen->whichBuf;
+ CursorSave(xw);
+ }
+
+ /*
+ * Do this last, since it may change the layout via a resize.
+ */
+ if (xw->misc.scrollbar) {
+ screen->fullVwin.sb_info.width = 0;
+ ScrollBarOn(xw, False);
+ }
+
+ return;
+}
+
+#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD
+
+/* limit this feature to recent XFree86 since X11R6.x core dumps */
+#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING)
+#define USE_XIM_INSTANTIATE_CB
+
+static void
+xim_instantiate_cb(Display * display,
+ XPointer client_data GCC_UNUSED,
+ XPointer call_data GCC_UNUSED)
+{
+ TRACE(("xim_instantiate_cb client=%p, call=%p\n", client_data, call_data));
+
+ if (display == XtDisplay(term)) {
+ VTInitI18N(term);
+ }
+}
+
+static void
+xim_destroy_cb(XIM im GCC_UNUSED,
+ XPointer client_data GCC_UNUSED,
+ XPointer call_data GCC_UNUSED)
+{
+ XtermWidget xw = term;
+ TInput *input = lookupTInput(xw, (Widget) xw);
+
+ TRACE(("xim_destroy_cb im=%lx, client=%p, call=%p\n",
+ (long) im, client_data, call_data));
+ if (input)
+ input->xic = NULL;
+ XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
+ xim_instantiate_cb, NULL);
+}
+#endif /* X11R6+ */
+
+static Boolean
+xim_create_fs(XtermWidget xw)
+{
+ XFontStruct **fonts;
+ char **font_name_list;
+ char **missing_charset_list;
+ char *def_string;
+ int missing_charset_count;
+ unsigned i, j;
+
+ if (xw->misc.xim_fs == 0) {
+ xw->misc.xim_fs = XCreateFontSet(XtDisplay(xw),
+ xw->misc.f_x,
+ &missing_charset_list,
+ &missing_charset_count,
+ &def_string);
+ if (xw->misc.xim_fs == NULL) {
+ xtermWarning("Preparation of font set "
+ "\"%s\" for XIM failed.\n", xw->misc.f_x);
+ xw->misc.xim_fs = XCreateFontSet(XtDisplay(xw),
+ DEFXIMFONT,
+ &missing_charset_list,
+ &missing_charset_count,
+ &def_string);
+ }
+ }
+ if (xw->misc.xim_fs == NULL) {
+ xtermWarning("Preparation of default font set "
+ "\"%s\" for XIM failed.\n", DEFXIMFONT);
+ cleanupInputMethod(xw);
+ xw->misc.cannot_im = True;
+ } else {
+ (void) XExtentsOfFontSet(xw->misc.xim_fs);
+ j = (unsigned) XFontsOfFontSet(xw->misc.xim_fs, &fonts, &font_name_list);
+ for (i = 0, xw->misc.xim_fs_ascent = 0; i < j; i++) {
+ if (xw->misc.xim_fs_ascent < (*fonts)->ascent)
+ xw->misc.xim_fs_ascent = (*fonts)->ascent;
+ }
+ }
+ return (Boolean) ! (xw->misc.cannot_im);
+}
+
+static void
+xim_create_xic(XtermWidget xw, Widget theInput)
+{
+ Display *myDisplay = XtDisplay(theInput);
+ Window myWindow = XtWindow(theInput);
+ unsigned i, j;
+ char *p = NULL, *s, *t, *ns, *end, buf[32];
+ XIMStyles *xim_styles;
+ XIMStyle input_style = 0;
+ Bool found;
+ static struct {
+ const char *name;
+ unsigned long code;
+ } known_style[] = {
+ {
+ "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing)
+ },
+ {
+ "OffTheSpot", (XIMPreeditArea | XIMStatusArea)
+ },
+ {
+ "Root", (XIMPreeditNothing | XIMStatusNothing)
+ },
+ };
+ TInput *input = lookupTInput(xw, theInput);
+
+ if (xw->misc.cannot_im) {
+ return;
+ }
+
+ if (input == 0) {
+ for (i = 0; i < NINPUTWIDGETS; ++i) {
+ if (xw->misc.inputs[i].w == 0) {
+ input = xw->misc.inputs + i;
+ input->w = theInput;
+ break;
+ }
+ }
+ }
+
+ if (input == 0) {
+ xtermWarning("attempted to add too many input widgets\n");
+ return;
+ }
+
+ TRACE(("xim_real_init\n"));
+
+ if (IsEmpty(xw->misc.input_method)) {
+ if ((p = XSetLocaleModifiers("")) != NULL && *p) {
+ input->xim = XOpenIM(myDisplay, NULL, NULL, NULL);
+ }
+ } else {
+ s = xw->misc.input_method;
+ i = 5 + (unsigned) strlen(s);
+
+ t = (char *) MyStackAlloc(i, buf);
+ if (t == NULL) {
+ SysError(ERROR_VINIT);
+ } else {
+
+ for (ns = s; ns && *s;) {
+ while (*s && isspace(CharOf(*s)))
+ s++;
+ if (!*s)
+ break;
+ if ((ns = end = strchr(s, ',')) == 0)
+ end = s + strlen(s);
+ while ((end != s) && isspace(CharOf(end[-1])))
+ end--;
+
+ if (end != s) {
+ strcpy(t, "@im=");
+ strncat(t, s, (size_t) (end - s));
+
+ if ((p = XSetLocaleModifiers(t)) != 0 && *p
+ && (input->xim = XOpenIM(myDisplay,
+ NULL,
+ NULL,
+ NULL)) != 0) {
+ break;
+ }
+
+ }
+ s = ns + 1;
+ }
+ MyStackFree(t, buf);
+ }
+ }
+
+ if (input->xim == NULL
+ && (p = XSetLocaleModifiers("@im=none")) != NULL
+ && *p) {
+ input->xim = XOpenIM(myDisplay, NULL, NULL, NULL);
+ }
+
+ if (!input->xim) {
+ xtermWarning("Failed to open input method\n");
+ return;
+ }
+ TRACE(("VTInitI18N opened input method:%s\n", NonNull(p)));
+
+ if (XGetIMValues(input->xim, XNQueryInputStyle, &xim_styles, (void *) 0)
+ || !xim_styles
+ || !xim_styles->count_styles) {
+ xtermWarning("input method doesn't support any style\n");
+ cleanupInputMethod(xw);
+ xw->misc.cannot_im = True;
+ return;
+ }
+
+ found = False;
+ for (s = xw->misc.preedit_type; s && !found;) {
+ while (*s && isspace(CharOf(*s)))
+ s++;
+ if (!*s)
+ break;
+ if ((ns = end = strchr(s, ',')) != 0)
+ ns++;
+ else
+ end = s + strlen(s);
+ while ((end != s) && isspace(CharOf(end[-1])))
+ end--;
+
+ if (end != s) { /* just in case we have a spurious comma */
+ TRACE(("looking for style '%.*s'\n", (int) (end - s), s));
+ for (i = 0; i < XtNumber(known_style); i++) {
+ if ((int) strlen(known_style[i].name) == (end - s)
+ && !strncmp(s, known_style[i].name, (size_t) (end - s))) {
+ input_style = known_style[i].code;
+ for (j = 0; j < xim_styles->count_styles; j++) {
+ if (input_style == xim_styles->supported_styles[j]) {
+ found = True;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ }
+ }
+
+ s = ns;
+ }
+ XFree(xim_styles);
+
+ if (!found) {
+ xtermWarning("input method doesn't support my preedit type (%s)\n",
+ xw->misc.preedit_type);
+ cleanupInputMethod(xw);
+ xw->misc.cannot_im = True;
+ return;
+ }
+
+ /*
+ * Check for styles we do not yet support.
+ */
+ TRACE(("input_style %#lx\n", input_style));
+ if (input_style == (XIMPreeditArea | XIMStatusArea)) {
+ xtermWarning("This program doesn't support the 'OffTheSpot' preedit type\n");
+ cleanupInputMethod(xw);
+ xw->misc.cannot_im = True;
+ return;
+ }
+
+ /*
+ * For XIMPreeditPosition (or OverTheSpot), XIM client has to
+ * prepare a font.
+ * The font has to be locale-dependent XFontSet, whereas
+ * XTerm use Unicode font. This leads a problem that the
+ * same font cannot be used for XIM preedit.
+ */
+ if (input_style != (XIMPreeditNothing | XIMStatusNothing)) {
+ XVaNestedList p_list;
+ XPoint spot =
+ {0, 0};
+
+ if (xim_create_fs(xw)) {
+ p_list = XVaCreateNestedList(0,
+ XNSpotLocation, &spot,
+ XNFontSet, xw->misc.xim_fs,
+ (void *) 0);
+ input->xic = XCreateIC(input->xim,
+ XNInputStyle, input_style,
+ XNClientWindow, myWindow,
+ XNFocusWindow, myWindow,
+ XNPreeditAttributes, p_list,
+ (void *) 0);
+ }
+ } else {
+ input->xic = XCreateIC(input->xim, XNInputStyle, input_style,
+ XNClientWindow, myWindow,
+ XNFocusWindow, myWindow,
+ (void *) 0);
+ }
+
+ if (!input->xic) {
+ xtermWarning("Failed to create input context\n");
+ cleanupInputMethod(xw);
+ }
+#if defined(USE_XIM_INSTANTIATE_CB)
+ else {
+ XIMCallback destroy_cb;
+
+ destroy_cb.callback = xim_destroy_cb;
+ destroy_cb.client_data = NULL;
+ if (XSetIMValues(input->xim,
+ XNDestroyCallback,
+ &destroy_cb,
+ (void *) 0)) {
+ xtermWarning("Could not set destroy callback to IM\n");
+ }
+ }
+#endif
+
+ return;
+}
+
+static void
+xim_real_init(XtermWidget xw)
+{
+ xim_create_xic(xw, (Widget) xw);
+}
+
+static void
+VTInitI18N(XtermWidget xw)
+{
+ if (xw->misc.open_im) {
+ xim_real_init(xw);
+
+#if defined(USE_XIM_INSTANTIATE_CB)
+ if (lookupTInput(xw, (Widget) xw) == NULL
+ && !xw->misc.cannot_im
+ && xw->misc.retry_im-- > 0) {
+ sleep(3);
+ XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL,
+ xim_instantiate_cb, NULL);
+ }
+#endif
+ }
+}
+
+TInput *
+lookupTInput(XtermWidget xw, Widget w)
+{
+ TInput *result = 0;
+ unsigned n;
+
+ for (n = 0; n < NINPUTWIDGETS; ++n) {
+ if (xw->misc.inputs[n].w == w) {
+ result = xw->misc.inputs + n;
+ break;
+ }
+ }
+
+ return result;
+}
+#endif /* OPT_I18N_SUPPORT && OPT_INPUT_METHOD */
+
+static void
+set_cursor_outline_gc(XtermWidget xw,
+ Bool filled,
+ Pixel fg,
+ Pixel bg,
+ Pixel cc)
+{
+ TScreen *screen = TScreenOf(xw);
+ VTwin *win = WhichVWin(screen);
+ CgsEnum cgsId = gcVTcursOutline;
+
+ if (cc == bg)
+ cc = fg;
+
+ if (filled) {
+ setCgsFore(xw, win, cgsId, bg);
+ setCgsBack(xw, win, cgsId, cc);
+ } else {
+ setCgsFore(xw, win, cgsId, cc);
+ setCgsBack(xw, win, cgsId, bg);
+ }
+}
+
+static Boolean
+VTSetValues(Widget cur,
+ Widget request GCC_UNUSED,
+ Widget wnew,
+ ArgList args GCC_UNUSED,
+ Cardinal *num_args GCC_UNUSED)
+{
+ XtermWidget curvt = (XtermWidget) cur;
+ XtermWidget newvt = (XtermWidget) wnew;
+ Boolean refresh_needed = False;
+ Boolean fonts_redone = False;
+
+ if ((T_COLOR(TScreenOf(curvt), TEXT_BG) !=
+ T_COLOR(TScreenOf(newvt), TEXT_BG)) ||
+ (T_COLOR(TScreenOf(curvt), TEXT_FG) !=
+ T_COLOR(TScreenOf(newvt), TEXT_FG)) ||
+ (TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) !=
+ TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) ||
+ (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)) {
+ if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
+ TScreenOf(newvt)->MenuFontName(fontMenu_default) = newvt->misc.default_font.f_n;
+ if (xtermLoadFont(newvt,
+ xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)),
+ True, TScreenOf(newvt)->menu_font_number)) {
+ /* resizing does the redisplay, so don't ask for it here */
+ refresh_needed = True;
+ fonts_redone = True;
+ } else if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)
+ TScreenOf(newvt)->MenuFontName(fontMenu_default) = curvt->misc.default_font.f_n;
+ }
+ if (!fonts_redone
+ && (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) !=
+ T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) {
+ if (set_cursor_gcs(newvt))
+ refresh_needed = True;
+ }
+ if (curvt->misc.re_verse != newvt->misc.re_verse) {
+ newvt->flags ^= REVERSE_VIDEO;
+ ReverseVideo(newvt);
+ /* ReverseVideo toggles */
+ newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse);
+ refresh_needed = True;
+ }
+ if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) !=
+ T_COLOR(TScreenOf(newvt), MOUSE_FG)) ||
+ (T_COLOR(TScreenOf(curvt), MOUSE_BG) !=
+ T_COLOR(TScreenOf(newvt), MOUSE_BG))) {
+ recolor_cursor(TScreenOf(newvt),
+ TScreenOf(newvt)->pointer_cursor,
+ T_COLOR(TScreenOf(newvt), MOUSE_FG),
+ T_COLOR(TScreenOf(newvt), MOUSE_BG));
+ refresh_needed = True;
+ }
+ if (curvt->misc.scrollbar != newvt->misc.scrollbar) {
+ ToggleScrollBar(newvt);
+ }
+
+ return refresh_needed;
+}
+
+#define setGC(code) set_at = __LINE__, currentCgs = code
+
+#define OutsideSelection(screen,srow,scol) \
+ ((srow) > (screen)->endH.row || \
+ ((srow) == (screen)->endH.row && \
+ (scol) >= (screen)->endH.col) || \
+ (srow) < (screen)->startH.row || \
+ ((srow) == (screen)->startH.row && \
+ (scol) < (screen)->startH.col))
+
+/*
+ * Shows cursor at new cursor position in screen.
+ */
+void
+ShowCursor(void)
+{
+ XtermWidget xw = term;
+ TScreen *screen = TScreenOf(xw);
+ int x, y;
+ IChar base;
+ unsigned flags;
+ CellColor fg_bg = 0;
+ GC currentGC;
+ GC outlineGC;
+ CgsEnum currentCgs = gcMAX;
+ VTwin *currentWin = WhichVWin(screen);
+ int set_at;
+ Bool in_selection;
+ Bool reversed;
+ Bool filled;
+ Pixel fg_pix;
+ Pixel bg_pix;
+ Pixel tmp;
+#if OPT_HIGHLIGHT_COLOR
+ Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG);
+ Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG);
+ Boolean use_selbg;
+ Boolean use_selfg;
+#endif
+#if OPT_WIDE_CHARS
+ size_t off;
+ int my_col = 0;
+#endif
+ int cursor_col;
+ LineData *ld = 0;
+
+ if (screen->cursor_state == BLINKED_OFF)
+ return;
+
+ if (screen->eventMode != NORMAL)
+ return;
+
+ if (INX2ROW(screen, screen->cur_row) > screen->max_row)
+ return;
+
+ screen->cursorp.row = screen->cur_row;
+ cursor_col = screen->cursorp.col = screen->cur_col;
+ screen->cursor_moved = False;
+
+#ifndef NO_ACTIVE_ICON
+ if (IsIcon(screen)) {
+ screen->cursor_state = ON;
+ return;
+ }
+#endif /* NO_ACTIVE_ICON */
+
+ ld = getLineData(screen, screen->cur_row);
+
+ base = ld->charData[cursor_col];
+ flags = ld->attribs[cursor_col];
+
+ if_OPT_WIDE_CHARS(screen, {
+ if (base == HIDDEN_CHAR && cursor_col > 0) {
+ /* if cursor points to non-initial part of wide character,
+ * back it up
+ */
+ --cursor_col;
+ base = ld->charData[cursor_col];
+ }
+ my_col = cursor_col;
+ if (base == 0)
+ base = ' ';
+ if (isWide((int) base))
+ my_col += 1;
+ });
+
+ if (base == 0) {
+ base = ' ';
+ }
+#if OPT_ISO_COLORS
+#ifdef EXP_BOGUS_FG
+ /*
+ * If the cursor happens to be on blanks, and we have not set both
+ * foreground and background color, do not treat it as a colored cell.
+ */
+ if (base == ' ') {
+ if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
+ TRACE(("ShowCursor - do not treat as a colored cell\n"));
+ flags &= ~(FG_COLOR | BG_COLOR);
+ } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
+ TRACE(("ShowCursor - should we treat as a colored cell?\n"));
+ if (!(xw->flags & FG_COLOR))
+ if (CheckBogusForeground(screen, "ShowCursor"))
+ flags &= ~(FG_COLOR | BG_COLOR);
+ }
+ }
+#else /* !EXP_BOGUS_FG */
+ /*
+ * If the cursor happens to be on blanks, and the foreground color is set
+ * but not the background, do not treat it as a colored cell.
+ */
+ if ((flags & TERM_COLOR_FLAGS(xw)) == BG_COLOR
+ && base == ' ') {
+ flags &= ~TERM_COLOR_FLAGS(xw);
+ }
+#endif
+#endif
+
+ /*
+ * Compare the current cell to the last set of colors used for the
+ * cursor and update the GC's if needed.
+ */
+ if_OPT_ISO_COLORS(screen, {
+ fg_bg = ld->color[cursor_col];
+ });
+
+ fg_pix = getXtermForeground(xw, flags, extract_fg(xw, fg_bg, flags));
+ bg_pix = getXtermBackground(xw, flags, extract_bg(xw, fg_bg, flags));
+
+ if (OutsideSelection(screen, screen->cur_row, screen->cur_col))
+ in_selection = False;
+ else
+ in_selection = True;
+
+ reversed = ReverseOrHilite(screen, flags, in_selection);
+
+ /* This is like updatedXtermGC(), except that we have to worry about
+ * whether the window has focus, since in that case we want just an
+ * outline for the cursor.
+ */
+ filled = (screen->select || screen->always_highlight) && !screen->cursor_underline;
+#if OPT_HIGHLIGHT_COLOR
+ use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix);
+ use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix);
+#endif
+ if (filled) {
+ if (reversed) { /* text is reverse video */
+ if (getCgsGC(xw, currentWin, gcVTcursNormal)) {
+ setGC(gcVTcursNormal);
+ } else {
+ if (flags & BOLDATTR(screen)) {
+ setGC(gcBold);
+ } else {
+ setGC(gcNorm);
+ }
+ }
+ EXCHANGE(fg_pix, bg_pix, tmp);
+#if OPT_HIGHLIGHT_COLOR
+ if (screen->hilite_reverse) {
+ if (use_selbg && !use_selfg)
+ fg_pix = bg_pix;
+ if (use_selfg && !use_selbg)
+ bg_pix = fg_pix;
+ if (use_selbg)
+ bg_pix = selbg_pix;
+ if (use_selfg)
+ fg_pix = selfg_pix;
+ }
+#endif
+ } else { /* normal video */
+ if (getCgsGC(xw, currentWin, gcVTcursReverse)) {
+ setGC(gcVTcursReverse);
+ } else {
+ if (flags & BOLDATTR(screen)) {
+ setGC(gcBoldReverse);
+ } else {
+ setGC(gcNormReverse);
+ }
+ }
+ }
+ if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
+ setCgsBack(xw, currentWin, currentCgs, fg_pix);
+ }
+ setCgsFore(xw, currentWin, currentCgs, bg_pix);
+ } else { /* not selected */
+ if (reversed) { /* text is reverse video */
+ EXCHANGE(fg_pix, bg_pix, tmp);
+ setGC(gcNormReverse);
+ } else { /* normal video */
+ setGC(gcNorm);
+ }
+#if OPT_HIGHLIGHT_COLOR
+ if (screen->hilite_reverse) {
+ if (in_selection && !reversed) {
+ /* EMPTY */
+ /* really INVERSE ... */
+ ;
+ } else if (in_selection || reversed) {
+ if (use_selbg) {
+ if (use_selfg) {
+ bg_pix = fg_pix;
+ } else {
+ fg_pix = bg_pix;
+ }
+ }
+ if (use_selbg) {
+ bg_pix = selbg_pix;
+ }
+ if (use_selfg) {
+ fg_pix = selfg_pix;
+ }
+ }
+ } else {
+ if (in_selection) {
+ if (use_selbg) {
+ bg_pix = selbg_pix;
+ }
+ if (use_selfg) {
+ fg_pix = selfg_pix;
+ }
+ }
+ }
+#endif
+ setCgsFore(xw, currentWin, currentCgs, fg_pix);
+ setCgsBack(xw, currentWin, currentCgs, bg_pix);
+ }
+
+ if (screen->cursor_busy == 0
+ && (screen->cursor_state != ON || screen->cursor_GC != set_at)) {
+
+ screen->cursor_GC = set_at;
+ TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n",
+ screen->cur_row, screen->cur_col,
+ (filled ? "filled" : "outline"),
+ (screen->cursor_underline ? "underline" : "box"),
+ set_at));
+
+ currentGC = getCgsGC(xw, currentWin, currentCgs);
+ x = LineCursorX(screen, ld, cursor_col);
+ y = CursorY(screen, screen->cur_row);
+
+ if (screen->cursor_underline) {
+ /*
+ * Overriding the combination of filled, reversed, in_selection is
+ * too complicated since the underline and the text-cell use
+ * different rules. Just redraw the text-cell, and draw the
+ * underline on top of it.
+ */
+ HideCursor();
+
+ /*
+ * Our current-GC is likely to have been modified in HideCursor().
+ * Set up a new request.
+ */
+ if (filled) {
+ if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) {
+ setCgsBack(xw, currentWin, currentCgs, fg_pix);
+ }
+ setCgsFore(xw, currentWin, currentCgs, bg_pix);
+ } else {
+ setCgsFore(xw, currentWin, currentCgs, fg_pix);
+ setCgsBack(xw, currentWin, currentCgs, bg_pix);
+ }
+ }
+
+ /*
+ * Update the outline-gc, to keep the cursor color distinct from the
+ * background color.
+ */
+ set_cursor_outline_gc(xw,
+ filled,
+ fg_pix,
+ bg_pix,
+ T_COLOR(screen, TEXT_CURSOR));
+
+ outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline);
+ if (outlineGC == 0)
+ outlineGC = currentGC;
+
+ if (screen->cursor_underline) {
+
+ /*
+ * Finally, draw the underline.
+ */
+ screen->box->x = (short) x;
+ screen->box->y = (short) (y + FontHeight(screen) - 2);
+ XDrawLines(screen->display, VWindow(screen), outlineGC,
+ screen->box, NBOX, CoordModePrevious);
+ } else {
+
+ drawXtermText(xw, flags & DRAWX_MASK,
+ currentGC, x, y,
+ LineCharSet(screen, ld),
+ &base, 1, 0);
+
+#if OPT_WIDE_CHARS
+ if_OPT_WIDE_CHARS(screen, {
+ for_each_combData(off, ld) {
+ if (!(ld->combData[off][my_col]))
+ break;
+ drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
+ currentGC, x, y,
+ LineCharSet(screen, ld),
+ ld->combData[off] + my_col,
+ 1, isWide((int) base));
+ }
+ });
+#endif
+
+ if (!filled) {
+ screen->box->x = (short) x;
+ screen->box->y = (short) y;
+ XDrawLines(screen->display, VWindow(screen), outlineGC,
+ screen->box, NBOX, CoordModePrevious);
+ }
+ }
+ }
+ screen->cursor_state = ON;
+
+ return;
+}
+
+/*
+ * hide cursor at previous cursor position in screen.
+ */
+void
+HideCursor(void)
+{
+ XtermWidget xw = term;
+ TScreen *screen = TScreenOf(xw);
+ GC currentGC;
+ int x, y;
+ IChar base;
+ unsigned flags;
+ CellColor fg_bg = 0;
+ Bool in_selection;
+#if OPT_WIDE_CHARS
+ size_t off;
+ int my_col = 0;
+#endif
+ int cursor_col;
+ LineData *ld = 0;
+
+ if (screen->cursor_state == OFF)
+ return;
+ if (INX2ROW(screen, screen->cursorp.row) > screen->max_row)
+ return;
+
+ cursor_col = screen->cursorp.col;
+
+#ifndef NO_ACTIVE_ICON
+ if (IsIcon(screen)) {
+ screen->cursor_state = OFF;
+ return;
+ }
+#endif /* NO_ACTIVE_ICON */
+
+ ld = getLineData(screen, screen->cursorp.row);
+
+ base = ld->charData[cursor_col];
+ flags = ld->attribs[cursor_col];
+
+ if_OPT_WIDE_CHARS(screen, {
+ if (base == HIDDEN_CHAR && cursor_col > 0) {
+ /* if cursor points to non-initial part of wide character,
+ * back it up
+ */
+ --cursor_col;
+ base = ld->charData[cursor_col];
+ }
+ my_col = cursor_col;
+ if (base == 0)
+ base = ' ';
+ if (isWide((int) base))
+ my_col += 1;
+ });
+
+ if (base == 0) {
+ base = ' ';
+ }
+#ifdef EXP_BOGUS_FG
+ /*
+ * If the cursor happens to be on blanks, and we have not set both
+ * foreground and background color, do not treat it as a colored cell.
+ */
+#if OPT_ISO_COLORS
+ if (base == ' ') {
+ if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) {
+ TRACE(("HideCursor - do not treat as a colored cell\n"));
+ flags &= ~(FG_COLOR | BG_COLOR);
+ } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) {
+ TRACE(("HideCursor - should we treat as a colored cell?\n"));
+ if (!(xw->flags & FG_COLOR))
+ if (CheckBogusForeground(screen, "HideCursor"))
+ flags &= ~(FG_COLOR | BG_COLOR);
+ }
+ }
+#endif
+#endif
+#if OPT_ISO_COLORS
+ fg_bg = 0;
+#endif
+
+ /*
+ * Compare the current cell to the last set of colors used for the
+ * cursor and update the GC's if needed.
+ */
+ if_OPT_ISO_COLORS(screen, {
+ fg_bg = ld->color[cursor_col];
+ });
+
+ if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col))
+ in_selection = False;
+ else
+ in_selection = True;
+
+ currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection);
+
+ TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n",
+ screen->cursorp.row, screen->cursorp.col));
+
+ x = LineCursorX(screen, ld, cursor_col);
+ y = CursorY(screen, screen->cursorp.row);
+
+ drawXtermText(xw, flags & DRAWX_MASK,
+ currentGC, x, y,
+ LineCharSet(screen, ld),
+ &base, 1, 0);
+
+#if OPT_WIDE_CHARS
+ if_OPT_WIDE_CHARS(screen, {
+ for_each_combData(off, ld) {
+ if (!(ld->combData[off][my_col]))
+ break;
+ drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND,
+ currentGC, x, y,
+ LineCharSet(screen, ld),
+ ld->combData[off] + my_col,
+ 1, isWide((int) base));
+ }
+ });
+#endif
+ screen->cursor_state = OFF;
+ resetXtermGC(xw, flags, in_selection);
+
+ return;
+}
+
+#if OPT_BLINK_CURS || OPT_BLINK_TEXT
+static void
+StartBlinking(TScreen * screen)
+{
+ if (screen->blink_timer == 0) {
+ unsigned long interval = (unsigned long) ((screen->cursor_state == ON)
+ ? screen->blink_on
+ : screen->blink_off);
+ if (interval == 0) /* wow! */
+ interval = 1; /* let's humor him anyway */
+ screen->blink_timer = XtAppAddTimeOut(app_con,
+ interval,
+ HandleBlinking,
+ screen);
+ }
+}
+
+static void
+StopBlinking(TScreen * screen)
+{
+ if (screen->blink_timer) {
+ XtRemoveTimeOut(screen->blink_timer);
+ screen->blink_timer = 0;
+ reallyStopBlinking(screen);
+ } else {
+ screen->blink_timer = 0;
+ }
+}
+
+#if OPT_BLINK_TEXT
+Bool
+LineHasBlinking(TScreen * screen, LineData * ld)
+{
+ int col;
+ Bool result = False;
+
+ for (col = 0; col < MaxCols(screen); ++col) {
+ if (ld->attribs[col] & BLINK) {
+ result = True;
+ break;
+ }
+ }
+ return result;
+}
+#endif
+
+/*
+ * Blink the cursor by alternately showing/hiding cursor. We leave the timer
+ * running all the time (even though that's a little inefficient) to make the
+ * logic simple.
+ */
+static void
+HandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED)
+{
+ TScreen *screen = (TScreen *) closure;
+ Bool resume = False;
+
+ screen->blink_timer = 0;
+ screen->blink_state = !screen->blink_state;
+
+#if OPT_BLINK_CURS
+ if (DoStartBlinking(screen)) {
+ if (screen->cursor_state == ON) {
+ if (screen->select || screen->always_highlight) {
+ HideCursor();
+ if (screen->cursor_state == OFF)
+ screen->cursor_state = BLINKED_OFF;
+ }
+ } else if (screen->cursor_state == BLINKED_OFF) {
+ screen->cursor_state = OFF;
+ ShowCursor();
+ if (screen->cursor_state == OFF)
+ screen->cursor_state = BLINKED_OFF;
+ }
+ resume = True;
+ }
+#endif
+
+#if OPT_BLINK_TEXT
+ /*
+ * Inspect the lines on the current screen to see if any have the BLINK flag
+ * associated with them. Prune off any that have had the corresponding
+ * cells reset. If any are left, repaint those lines with ScrnRefresh().
+ */
+ if (!(screen->blink_as_bold)) {
+ int row;
+ int first_row = screen->max_row;
+ int last_row = -1;
+
+ for (row = screen->max_row; row >= 0; row--) {
+ LineData *ld = getLineData(screen, ROW2INX(screen, row));
+
+ if (ld != 0 && LineTstBlinked(ld)) {
+ if (LineHasBlinking(screen, ld)) {
+ resume = True;
+ if (row > last_row)
+ last_row = row;
+ if (row < first_row)
+ first_row = row;
+ } else {
+ LineClrBlinked(ld);
+ }
+ }
+ }
+ /*
+ * FIXME: this could be a little more efficient, e.g,. by limiting the
+ * columns which are updated.
+ */
+ if (first_row <= last_row) {
+ ScrnRefresh(term,
+ first_row,
+ 0,
+ last_row + 1 - first_row,
+ MaxCols(screen),
+ True);
+ }
+ }
+#endif
+
+ /*
+ * If either the cursor or text is blinking, restart the timer.
+ */
+ if (resume)
+ StartBlinking(screen);
+}
+#endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */
+
+void
+RestartBlinking(TScreen * screen GCC_UNUSED)
+{
+#if OPT_BLINK_CURS || OPT_BLINK_TEXT
+ if (screen->blink_timer == 0) {
+ Bool resume = False;
+
+#if OPT_BLINK_CURS
+ if (DoStartBlinking(screen)) {
+ resume = True;
+ }
+#endif
+#if OPT_BLINK_TEXT
+ if (!resume) {
+ int row;
+
+ for (row = screen->max_row; row >= 0; row--) {
+ LineData *ld = getLineData(screen, ROW2INX(screen, row));
+
+ if (ld != 0 && LineTstBlinked(ld)) {
+ if (LineHasBlinking(screen, ld)) {
+ resume = True;
+ break;
+ }
+ }
+ }
+ }
+#endif
+ if (resume)
+ StartBlinking(screen);
+ }
+#endif
+}
+
+/*
+ * Implement soft or hard (full) reset of the VTxxx emulation. There are a
+ * couple of differences from real DEC VTxxx terminals (to avoid breaking
+ * applications which have come to rely on xterm doing this):
+ *
+ * + autowrap mode should be reset (instead it's reset to the resource
+ * default).
+ * + the popup menu offers a choice of resetting the savedLines, or not.
+ * (but the control sequence does this anyway).
+ */
+static void
+ReallyReset(XtermWidget xw, Bool full, Bool saved)
+{
+ static char empty[1];
+
+ TScreen *screen = TScreenOf(xw);
+
+ if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) {
+ Bell(xw, XkbBI_MinorError, 0);
+ return;
+ }
+
+ if (saved) {
+ screen->savedlines = 0;
+ ScrollBarDrawThumb(screen->scrollWidget);
+ }
+
+ /* make cursor visible */
+ screen->cursor_set = ON;
+
+ /* reset scrolling region */
+ reset_margins(screen);
+
+ bitclr(&xw->flags, ORIGIN);
+
+ if_OPT_ISO_COLORS(screen, {
+ reset_SGR_Colors(xw);
+ if (ResetAnsiColorRequest(xw, empty, 0))
+ xtermRepaint(xw);
+ });
+
+ /* Reset character-sets to initial state */
+ resetCharsets(screen);
+
+#if OPT_MOD_FKEYS
+ /* Reset modifier-resources to initial state */
+ xw->keyboard.modify_now = xw->keyboard.modify_1st;
+#endif
+
+ /* Reset DECSCA */
+ bitclr(&xw->flags, PROTECTED);
+ screen->protected_mode = OFF_PROTECT;
+
+ if (full) { /* RIS */
+ if (screen->bellOnReset)
+ Bell(xw, XkbBI_TerminalBell, 0);
+
+ /* reset the mouse mode */
+ screen->send_mouse_pos = MOUSE_OFF;
+ screen->send_focus_pos = OFF;
+ screen->extend_coords = 0;
+ screen->waitingForTrackInfo = False;
+ screen->eventMode = NORMAL;
+
+ xtermShowPointer(xw, True);
+
+ TabReset(xw->tabs);
+ xw->keyboard.flags = MODE_SRM;
+#if OPT_INITIAL_ERASE
+ if (xw->keyboard.reset_DECBKM == 1)
+ xw->keyboard.flags |= MODE_DECBKM;
+ else if (xw->keyboard.reset_DECBKM == 2)
+#endif
+ if (TScreenOf(xw)->backarrow_key)
+ xw->keyboard.flags |= MODE_DECBKM;
+ TRACE(("full reset DECBKM %s\n",
+ BtoS(xw->keyboard.flags & MODE_DECBKM)));
+ update_appcursor();
+ update_appkeypad();
+ update_decbkm();
+ show_8bit_control(False);
+ reset_decudk();
+
+ FromAlternate(xw);
+ ClearScreen(xw);
+ screen->cursor_state = OFF;
+ if (xw->flags & REVERSE_VIDEO)
+ ReverseVideo(xw);
+
+ xw->flags = xw->initflags;
+ update_reversevideo();
+ update_autowrap();
+ update_reversewrap();
+ update_autolinefeed();
+
+ screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL));
+ update_jumpscroll();
+
+ if (screen->c132 && (xw->flags & IN132COLUMNS)) {
+ Dimension reqWidth = (Dimension) (80 * FontWidth(screen)
+ + 2 * screen->border
+ + ScrollbarWidth(screen));
+ Dimension reqHeight = (Dimension) (FontHeight(screen)
+ * MaxRows(screen)
+ + 2 * screen->border);
+ Dimension replyWidth;
+ Dimension replyHeight;
+
+ TRACE(("Making resize-request to restore 80-columns %dx%d\n",
+ reqHeight, reqWidth));
+ REQ_RESIZE((Widget) xw,
+ reqWidth,
+ reqHeight,
+ &replyWidth, &replyHeight);
+ repairSizeHints();
+ XSync(screen->display, False); /* synchronize */
+ if (xtermAppPending())
+ xevents();
+ }
+
+ CursorSet(screen, 0, 0, xw->flags);
+ CursorSave(xw);
+ } else { /* DECSTR */
+ /*
+ * There's a tiny difference, to accommodate usage of xterm.
+ * We reset autowrap to the resource values rather than turning
+ * it off.
+ */
+ UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM));
+ bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP);
+ bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE);
+ if_OPT_ISO_COLORS(screen, {
+ reset_SGR_Colors(xw);
+ });
+ update_appcursor();
+ update_autowrap();
+ update_reversewrap();
+
+ CursorSave(xw);
+ screen->sc[screen->whichBuf].row =
+ screen->sc[screen->whichBuf].col = 0;
+ }
+}
+
+void
+VTReset(XtermWidget xw, Bool full, Bool saved)
+{
+ ReallyReset(xw, full, saved);
+ longjmp(vtjmpbuf, 1); /* force ground state in parser */
+}
+
+/*
+ * set_character_class - takes a string of the form
+ *
+ * low[-high]:val[,low[-high]:val[...]]
+ *
+ * and sets the indicated ranges to the indicated values.
+ */
+static int
+set_character_class(char *s)
+{
+#define FMT "%s in range string \"%s\" (position %d)\n"
+ int i; /* iterator, index into s */
+ int len; /* length of s */
+ int acc; /* accumulator */
+ int low, high; /* bounds of range [0..127] */
+ int base; /* 8, 10, 16 (octal, decimal, hex) */
+ int numbers; /* count of numbers per range */
+ int digits; /* count of digits in a number */
+
+ if (!s || !s[0])
+ return -1;
+
+ base = 10; /* in case we ever add octal, hex */
+ low = high = -1; /* out of range */
+
+ for (i = 0, len = (int) strlen(s), acc = 0, numbers = digits = 0;
+ i < len; i++) {
+ Char c = CharOf(s[i]);
+
+ if (isspace(c)) {
+ continue;
+ } else if (isdigit(c)) {
+ acc = acc * base + (c - '0');
+ digits++;
+ continue;
+ } else if (c == '-') {
+ low = acc;
+ acc = 0;
+ if (digits == 0) {
+ xtermWarning(FMT, "missing number", s, i);
+ return (-1);
+ }
+ digits = 0;
+ numbers++;
+ continue;
+ } else if (c == ':') {
+ if (numbers == 0)
+ low = acc;
+ else if (numbers == 1)
+ high = acc;
+ else {
+ xtermWarning(FMT, "too many numbers", s, i);
+ return (-1);
+ }
+ digits = 0;
+ numbers++;
+ acc = 0;
+ continue;
+ } else if (c == ',') {
+ /*
+ * now, process it
+ */
+
+ if (high < 0) {
+ high = low;
+ numbers++;
+ }
+ if (numbers != 2) {
+ xtermWarning(FMT, "bad value number", s, i);
+ } else if (SetCharacterClassRange(low, high, acc) != 0) {
+ xtermWarning(FMT, "bad range", s, i);
+ }
+
+ low = high = -1;
+ acc = 0;
+ digits = 0;
+ numbers = 0;
+ continue;
+ } else {
+ xtermWarning(FMT, "bad character", s, i);
+ return (-1);
+ } /* end if else if ... else */
+
+ }
+
+ if (low < 0 && high < 0)
+ return (0);
+
+ /*
+ * now, process it
+ */
+
+ if (high < 0)
+ high = low;
+ if (numbers < 1 || numbers > 2) {
+ xtermWarning(FMT, "bad value number", s, i);
+ } else if (SetCharacterClassRange(low, high, acc) != 0) {
+ xtermWarning(FMT, "bad range", s, i);
+ }
+
+ return (0);
+#undef FMT
+}
+
+/* ARGSUSED */
+static void
+HandleKeymapChange(Widget w,
+ XEvent * event GCC_UNUSED,
+ String * params,
+ Cardinal *param_count)
+{
+ static XtTranslations keymap, original;
+ static XtResource key_resources[] =
+ {
+ {XtNtranslations, XtCTranslations, XtRTranslationTable,
+ sizeof(XtTranslations), 0, XtRTranslationTable, (XtPointer) NULL}
+ };
+ char mapName[1000];
+ char mapClass[1000];
+ char *pmapName;
+ char *pmapClass;
+ size_t len;
+
+ if (*param_count != 1)
+ return;
+
+ if (original == NULL)
+ original = w->core.tm.translations;
+
+ if (strcmp(params[0], "None") == 0) {
+ XtOverrideTranslations(w, original);
+ return;
+ }
+
+ len = strlen(params[0]) + 7;
+
+ pmapName = (char *) MyStackAlloc(len, mapName);
+ pmapClass = (char *) MyStackAlloc(len, mapClass);
+ if (pmapName == NULL
+ || pmapClass == NULL) {
+ SysError(ERROR_KMMALLOC1);
+ } else {
+
+ (void) sprintf(pmapName, "%sKeymap", params[0]);
+ (void) strcpy(pmapClass, pmapName);
+ if (islower(CharOf(pmapClass[0])))
+ pmapClass[0] = x_toupper(pmapClass[0]);
+ XtGetSubresources(w, (XtPointer) &keymap, pmapName, pmapClass,
+ key_resources, (Cardinal) 1, NULL, (Cardinal) 0);
+ if (keymap != NULL)
+ XtOverrideTranslations(w, keymap);
+
+ MyStackFree(pmapName, mapName);
+ MyStackFree(pmapClass, mapClass);
+ }
+}
+
+/* ARGSUSED */
+static void
+HandleBell(Widget w GCC_UNUSED,
+ XEvent * event GCC_UNUSED,
+ String * params, /* [0] = volume */
+ Cardinal *param_count) /* 0 or 1 */
+{
+ int percent = (*param_count) ? atoi(params[0]) : 0;
+
+ Bell(term, XkbBI_TerminalBell, percent);
+}
+
+/* ARGSUSED */
+static void
+HandleVisualBell(Widget w GCC_UNUSED,
+ XEvent * event GCC_UNUSED,
+ String * params GCC_UNUSED,
+ Cardinal *param_count GCC_UNUSED)
+{
+ VisualBell();
+}
+
+/* ARGSUSED */
+static void
+HandleIgnore(Widget w,
+ XEvent * event,
+ String * params GCC_UNUSED,
+ Cardinal *param_count GCC_UNUSED)
+{
+ XtermWidget xw;
+
+ TRACE(("Handle ignore for %p %s\n",
+ (void *) w, visibleEventType(event->type)));
+ if ((xw = getXtermWidget(w)) != 0) {
+ /* do nothing, but check for funny escape sequences */
+ (void) SendMousePosition(xw, event);
+ }
+}
+
+/* ARGSUSED */
+static void
+DoSetSelectedFont(Widget w,
+ XtPointer client_data GCC_UNUSED,
+ Atom * selection GCC_UNUSED,
+ Atom * type,
+ XtPointer value,
+ unsigned long *length,
+ int *format)
+{
+ XtermWidget xw = getXtermWidget(w);
+
+ if ((xw == 0) || *type != XA_STRING || *format != 8) {
+ Bell(xw, XkbBI_MinorError, 0);
+ } else {
+ Boolean failed = False;
+ int oldFont = TScreenOf(xw)->menu_font_number;
+ String save = TScreenOf(xw)->MenuFontName(fontMenu_fontsel);
+ char *val;
+ char *test = 0;
+ char *used = 0;
+ unsigned len = (unsigned) *length;
+ unsigned tst;
+
+ /*
+ * Some versions of X deliver null-terminated selections, some do not.
+ */
+ for (tst = 0; tst < len; ++tst) {
+ if (((char *) value)[tst] == '\0') {
+ len = tst;
+ break;
+ }
+ }
+
+ if (len > 0 && (val = TypeMallocN(char, len + 1)) != 0) {
+ memcpy(val, value, (size_t) len);
+ val[len] = '\0';
+ used = x_strtrim(val);
+ TRACE(("DoSetSelectedFont(%s)\n", used));
+ /* Do some sanity checking to avoid sending a long selection
+ back to the server in an OpenFont that is unlikely to succeed.
+ XLFD allows up to 255 characters and no control characters;
+ we are a little more liberal here. */
+ if (len < 1000
+ && !strchr(used, '\n')
+ && (test = x_strdup(used)) != 0) {
+ TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = test;
+ if (!xtermLoadFont(term,
+ xtermFontName(used),
+ True,
+ fontMenu_fontsel)) {
+ failed = True;
+ free(test);
+ TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = save;
+ }
+ } else {
+ failed = True;
+ }
+ if (failed) {
+ (void) xtermLoadFont(term,
+ xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)),
+ True,
+ oldFont);
+ Bell(xw, XkbBI_MinorError, 0);
+ }
+ free(used);
+ free(val);
+ }
+ }
+}
+
+void
+FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe)
+{
+ TScreen *screen = TScreenOf(xw);
+ static AtomPtr *atoms;
+ unsigned int atomCount = 0;
+ AtomPtr *pAtom;
+ unsigned a;
+ Atom target;
+
+ if (!atom_name)
+ atom_name = (screen->mappedSelect
+ ? screen->mappedSelect[0]
+ : "PRIMARY");
+ TRACE(("FindFontSelection(%s)\n", atom_name));
+
+ for (pAtom = atoms, a = atomCount; a; a--, pAtom++) {
+ if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0)
+ break;
+ }
+ if (!a) {
+ atoms = TypeXtReallocN(AtomPtr, atoms, atomCount + 1);
+ *(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name);
+ }
+
+ target = XmuInternAtom(XtDisplay(xw), *pAtom);
+ if (justprobe) {
+ screen->MenuFontName(fontMenu_fontsel) =
+ XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : 0;
+ TRACE(("...selected fontname '%s'\n",
+ NonNull(screen->MenuFontName(fontMenu_fontsel))));
+ } else {
+ XtGetSelectionValue((Widget) xw, target, XA_STRING,
+ DoSetSelectedFont, NULL,
+ XtLastTimestampProcessed(XtDisplay(xw)));
+ }
+ return;
+}
+
+Bool
+set_cursor_gcs(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ VTwin *win = WhichVWin(screen);
+
+ Pixel cc = T_COLOR(screen, TEXT_CURSOR);
+ Pixel fg = T_COLOR(screen, TEXT_FG);
+ Pixel bg = T_COLOR(screen, TEXT_BG);
+ Bool changed = False;
+
+ /*
+ * Let's see, there are three things that have "color":
+ *
+ * background
+ * text
+ * cursorblock
+ *
+ * And, there are four situations when drawing a cursor, if we decide
+ * that we like have a solid block of cursor color with the letter
+ * that it is highlighting shown in the background color to make it
+ * stand out:
+ *
+ * selected window, normal video - background on cursor
+ * selected window, reverse video - foreground on cursor
+ * unselected window, normal video - foreground on background
+ * unselected window, reverse video - background on foreground
+ *
+ * Since the last two are really just normalGC and reverseGC, we only
+ * need two new GC's. Under monochrome, we get the same effect as
+ * above by setting cursor color to foreground.
+ */
+
+ TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg));
+ if (win != 0 && (cc != bg)) {
+ /* set the fonts to the current one */
+ setCgsFont(xw, win, gcVTcursNormal, 0);
+ setCgsFont(xw, win, gcVTcursFilled, 0);
+ setCgsFont(xw, win, gcVTcursReverse, 0);
+ setCgsFont(xw, win, gcVTcursOutline, 0);
+
+ /* we have a colored cursor */
+ setCgsFore(xw, win, gcVTcursNormal, fg);
+ setCgsBack(xw, win, gcVTcursNormal, cc);
+
+ setCgsFore(xw, win, gcVTcursFilled, cc);
+ setCgsBack(xw, win, gcVTcursFilled, fg);
+
+ if (screen->always_highlight) {
+ /* both GC's use the same color */
+ setCgsFore(xw, win, gcVTcursReverse, bg);
+ setCgsBack(xw, win, gcVTcursReverse, cc);
+ } else {
+ setCgsFore(xw, win, gcVTcursReverse, bg);
+ setCgsBack(xw, win, gcVTcursReverse, cc);
+ }
+ set_cursor_outline_gc(xw, screen->always_highlight, fg, bg, cc);
+ changed = True;
+ }
+
+ if (changed) {
+ TRACE(("...set_cursor_gcs - done\n"));
+ }
+ return changed;
+}
+
+/*
+ * Build up the default translations string, allowing the user to suppress
+ * some of the features.
+ */
+void
+VTInitTranslations(void)
+{
+ /* *INDENT-OFF* */
+ static struct {
+ Boolean wanted;
+ const char *name;
+ const char *value;
+ } table[] = {
+ {
+ False,
+ "default",
+"\
+ Shift <KeyPress> Prior:scroll-back(1,halfpage) \n\
+ Shift <KeyPress> Next:scroll-forw(1,halfpage) \n\
+ Shift <KeyPress> Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\
+ Shift <KeyPress> Insert:insert-selection(SELECT, CUT_BUFFER0) \n\
+"
+ },
+#if OPT_MAXIMIZE
+ {
+ False,
+ "fullscreen",
+"\
+ Alt <Key>Return:fullscreen() \n\
+"
+ },
+#endif
+#if OPT_SCROLL_LOCK
+ {
+ False,
+ "scroll-lock",
+"\
+ <KeyRelease> Scroll_Lock:scroll-lock() \n\
+"
+ },
+#endif
+#if OPT_SHIFT_FONTS
+ {
+ False,
+ "shift-fonts",
+"\
+ Shift~Ctrl <KeyPress> KP_Add:larger-vt-font() \n\
+ Shift Ctrl <KeyPress> KP_Add:smaller-vt-font() \n\
+ Shift <KeyPress> KP_Subtract:smaller-vt-font() \n\
+"
+ },
+#endif
+ /* PROCURA added "Meta <Btn2Down>:clear-saved-lines()" */
+ {
+ False,
+ "default",
+"\
+ ~Meta <KeyPress>:insert-seven-bit() \n\
+ Meta <KeyPress>:insert-eight-bit() \n\
+ !Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
+ !Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
+ !Lock Ctrl @Num_Lock <Btn1Down>:popup-menu(mainMenu) \n\
+ ! @Num_Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\
+ ~Meta <Btn1Down>:select-start() \n\
+ ~Meta <Btn1Motion>:select-extend() \n\
+ !Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
+ !Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
+ !Lock Ctrl @Num_Lock <Btn2Down>:popup-menu(vtMenu) \n\
+ ! @Num_Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\
+ ~Ctrl ~Meta <Btn2Down>:ignore() \n\
+ Meta <Btn2Down>:clear-saved-lines() \n\
+ ~Ctrl ~Meta <Btn2Up>:insert-selection(SELECT, CUT_BUFFER0) \n\
+ !Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
+ !Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
+ !Lock Ctrl @Num_Lock <Btn3Down>:popup-menu(fontMenu) \n\
+ ! @Num_Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\
+ ~Ctrl ~Meta <Btn3Down>:start-extend() \n\
+ ~Meta <Btn3Motion>:select-extend() \n\
+"
+ },
+ {
+ False,
+ "wheel-mouse",
+"\
+ Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
+ Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
+ Lock @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
+ @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\
+ <Btn4Down>:scroll-back(5,line,m) \n\
+ Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
+ Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
+ Lock @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
+ @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\
+ <Btn5Down>:scroll-forw(5,line,m) \n\
+"
+ },
+ {
+ False,
+ "default",
+"\
+ <BtnUp>:select-end(SELECT, CUT_BUFFER0) \n\
+ <BtnDown>:ignore() \
+"
+ }
+ };
+ /* *INDENT-ON* */
+
+ size_t needed = 0;
+ char *result = 0;
+
+ int pass;
+ Cardinal item;
+
+ TRACE(("VTInitTranslations\n"));
+ for (item = 0; item < XtNumber(table); ++item) {
+ table[item].wanted = True;
+ }
+#if OPT_MAXIMIZE
+ /*
+ * As a special case, allow for disabling the alt-enter translation if
+ * the resource settings prevent fullscreen from being used. We would
+ * do the same for scroll-lock and shift-fonts if they were application
+ * resources too, rather than in the widget.
+ */
+ if (resource.fullscreen == esNever) {
+ for (item = 0; item < XtNumber(table); ++item) {
+ if (!strcmp(table[item].name, "fullscreen")) {
+ table[item].wanted = False;
+ TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value));
+ }
+ }
+ }
+#endif
+ if (!IsEmpty(resource.omitTranslation)) {
+ char *value;
+ const char *source = resource.omitTranslation;
+
+ while (*source != '\0' && (value = ParseList(&source)) != 0) {
+ size_t len = strlen(value);
+
+ TRACE(("parsed:%s\n", value));
+ for (item = 0; item < XtNumber(table); ++item) {
+ if (strlen(table[item].name) >= len
+ && x_strncasecmp(table[item].name,
+ value,
+ (unsigned) len) == 0) {
+ table[item].wanted = False;
+ TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value));
+ break;
+ }
+ }
+ free(value);
+ }
+ }
+
+ for (pass = 0; pass < 2; ++pass) {
+ needed = 0;
+ for (item = 0; item < XtNumber(table); ++item) {
+ if (table[item].wanted) {
+ if (pass) {
+ strcat(result, table[item].value);
+ } else {
+ needed += strlen(table[item].value) + 1;
+ }
+ }
+ }
+ if (!pass) {
+ result = XtMalloc((Cardinal) needed);
+ *result = '\0';
+ }
+ }
+
+ TRACE(("result:\n%s\n", result));
+
+ defaultTranslations = result;
+ xtermClassRec.core_class.tm_table = result;
+}
+
+#ifdef NO_LEAKS
+void
+noleaks_charproc(void)
+{
+ if (v_buffer != 0)
+ free(v_buffer);
+}
+#endif