charproc.c revision 913cc679
1/* $XTermId: charproc.c,v 1.1492 2017/06/19 08:34:54 tom Exp $ */ 2 3/* 4 * Copyright 1999-2016,2017 by Thomas E. Dickey 5 * 6 * All Rights Reserved 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * Except as contained in this notice, the name(s) of the above copyright 28 * holders shall not be used in advertising or otherwise to promote the 29 * sale, use or other dealings in this Software without prior written 30 * authorization. 31 * 32 * 33 * Copyright 1988 The Open Group 34 * 35 * Permission to use, copy, modify, distribute, and sell this software and its 36 * documentation for any purpose is hereby granted without fee, provided that 37 * the above copyright notice appear in all copies and that both that 38 * copyright notice and this permission notice appear in supporting 39 * documentation. 40 * 41 * The above copyright notice and this permission notice shall be included in 42 * all copies or substantial portions of the Software. 43 * 44 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 45 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 46 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 47 * OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 48 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 49 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 50 * 51 * Except as contained in this notice, the name of The Open Group shall not be 52 * used in advertising or otherwise to promote the sale, use or other dealings 53 * in this Software without prior written authorization from The Open Group. 54 * 55 */ 56/* 57 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 58 * 59 * All Rights Reserved 60 * 61 * Permission to use, copy, modify, and distribute this software and its 62 * documentation for any purpose and without fee is hereby granted, 63 * provided that the above copyright notice appear in all copies and that 64 * both that copyright notice and this permission notice appear in 65 * supporting documentation, and that the name of Digital Equipment 66 * Corporation not be used in advertising or publicity pertaining to 67 * distribution of the software without specific, written prior permission. 68 * 69 * 70 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 71 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 72 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 73 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 74 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 75 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 76 * SOFTWARE. 77 */ 78 79/* charproc.c */ 80 81#include <version.h> 82#include <xterm.h> 83 84#include <X11/Xatom.h> 85#include <X11/Xutil.h> 86#include <X11/cursorfont.h> 87#include <X11/Xmu/Atoms.h> 88#include <X11/Xmu/CharSet.h> 89#include <X11/Xmu/Converters.h> 90 91#if OPT_INPUT_METHOD 92 93#if defined(HAVE_LIB_XAW) 94#include <X11/Xaw/XawImP.h> 95#elif defined(HAVE_LIB_XAW3D) 96#include <X11/Xaw3d/XawImP.h> 97#elif defined(HAVE_LIB_XAW3DXFT) 98#include <X11/Xaw3dxft/XawImP.h> 99#elif defined(HAVE_LIB_NEXTAW) 100#include <X11/neXtaw/XawImP.h> 101#elif defined(HAVE_LIB_XAWPLUS) 102#include <X11/XawPlus/XawImP.h> 103#endif 104 105#endif 106 107#if OPT_DOUBLE_BUFFER 108#include <X11/extensions/Xdbe.h> 109#endif 110 111#if OPT_WIDE_CHARS 112#include <xutf8.h> 113#include <wcwidth.h> 114#include <precompose.h> 115#ifdef HAVE_LANGINFO_CODESET 116#include <langinfo.h> 117#endif 118#endif 119 120#if OPT_INPUT_METHOD 121#include <X11/Xlocale.h> 122#endif 123 124#include <stdio.h> 125#include <ctype.h> 126#include <assert.h> 127 128#if defined(HAVE_SCHED_YIELD) 129#include <sched.h> 130#endif 131 132#include <VTparse.h> 133#include <data.h> 134#include <error.h> 135#include <menu.h> 136#include <main.h> 137#include <fontutils.h> 138#include <charclass.h> 139#include <xstrings.h> 140#include <graphics.h> 141 142typedef int (*BitFunc) (unsigned * /* p */ , 143 unsigned /* mask */ ); 144 145static IChar doinput(void); 146static int set_character_class(char * /*s */ ); 147static void FromAlternate(XtermWidget /* xw */ ); 148static void ReallyReset(XtermWidget /* xw */ , 149 Bool /* full */ , 150 Bool /* saved */ ); 151static void RequestResize(XtermWidget /* xw */ , 152 int /* rows */ , 153 int /* cols */ , 154 Bool /* text */ ); 155static void SwitchBufs(XtermWidget /* xw */ , 156 int /* toBuf */ , 157 Bool /* clearFirst */ ); 158static void ToAlternate(XtermWidget /* xw */ , 159 Bool /* clearFirst */ ); 160static void ansi_modes(XtermWidget termw, 161 BitFunc /* func */ ); 162static int bitclr(unsigned *p, unsigned mask); 163static int bitcpy(unsigned *p, unsigned q, unsigned mask); 164static int bitset(unsigned *p, unsigned mask); 165static void dpmodes(XtermWidget /* xw */ , 166 BitFunc /* func */ ); 167static void restoremodes(XtermWidget /* xw */ ); 168static void savemodes(XtermWidget /* xw */ ); 169static void window_ops(XtermWidget /* xw */ ); 170 171#define DoStartBlinking(s) ((s)->cursor_blink ^ (s)->cursor_blink_esc) 172 173#if OPT_BLINK_CURS || OPT_BLINK_TEXT 174#define UpdateCursorBlink(screen) SetCursorBlink(screen, screen->cursor_blink) 175static void SetCursorBlink(TScreen * /* screen */ , 176 Bool /* enable */ ); 177static void HandleBlinking(XtPointer /* closure */ , 178 XtIntervalId * /* id */ ); 179static void StartBlinking(TScreen * /* screen */ ); 180static void StopBlinking(TScreen * /* screen */ ); 181#else 182#define StartBlinking(screen) /* nothing */ 183#define StopBlinking(screen) /* nothing */ 184#endif 185 186#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 187static void PreeditPosition(XtermWidget /* xw */ ); 188#endif 189 190#define DEFAULT -1 191#define BELLSUPPRESSMSEC 200 192 193static ANSI reply; 194static PARAMS parms; 195 196#define nparam parms.count 197 198#define InitParams() parms.count = parms.is_sub[0] = parms.has_subparams = 0 199#define GetParam(n) parms.params[(n)] 200#define SetParam(n,v) parms.params[(n)] = v 201#define ParamPair(n) nparam - (n), parms.params + (n) 202#define ParamsDone() InitParams() 203 204static jmp_buf vtjmpbuf; 205 206/* event handlers */ 207static void HandleBell PROTO_XT_ACTIONS_ARGS; 208static void HandleIgnore PROTO_XT_ACTIONS_ARGS; 209static void HandleKeymapChange PROTO_XT_ACTIONS_ARGS; 210static void HandleVisualBell PROTO_XT_ACTIONS_ARGS; 211#if HANDLE_STRUCT_NOTIFY 212static void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS; 213#endif 214 215/* 216 * NOTE: VTInitialize zeros out the entire ".screen" component of the 217 * XtermWidget, so make sure to add an assignment statement in VTInitialize() 218 * for each new ".screen" field added to this resource list. 219 */ 220 221/* Defaults */ 222#if OPT_ISO_COLORS 223 224/* 225 * If we default to colorMode enabled, compile-in defaults for the ANSI colors. 226 */ 227#if DFT_COLORMODE 228#define DFT_COLOR(name) name 229#else 230#define DFT_COLOR(name) XtDefaultForeground 231#endif 232#endif 233 234static char _Font_Selected_[] = "yes"; /* string is arbitrary */ 235 236static const char *defaultTranslations; 237/* *INDENT-OFF* */ 238static XtActionsRec actionsList[] = { 239 { "allow-bold-fonts", HandleAllowBoldFonts }, 240 { "allow-send-events", HandleAllowSends }, 241 { "bell", HandleBell }, 242 { "clear-saved-lines", HandleClearSavedLines }, 243 { "copy-selection", HandleCopySelection }, 244 { "create-menu", HandleCreateMenu }, 245 { "delete-is-del", HandleDeleteIsDEL }, 246 { "dired-button", DiredButton }, 247 { "hard-reset", HandleHardReset }, 248 { "ignore", HandleIgnore }, 249 { "insert", HandleKeyPressed }, /* alias for insert-seven-bit */ 250 { "insert-eight-bit", HandleEightBitKeyPressed }, 251 { "insert-selection", HandleInsertSelection }, 252 { "insert-seven-bit", HandleKeyPressed }, 253 { "interpret", HandleInterpret }, 254 { "keymap", HandleKeymapChange }, 255 { "popup-menu", HandlePopupMenu }, 256 { "print", HandlePrintScreen }, 257 { "print-everything", HandlePrintEverything }, 258 { "print-redir", HandlePrintControlMode }, 259 { "quit", HandleQuit }, 260 { "redraw", HandleRedraw }, 261 { "scroll-back", HandleScrollBack }, 262 { "scroll-forw", HandleScrollForward }, 263 { "secure", HandleSecure }, 264 { "select-cursor-end", HandleKeyboardSelectEnd }, 265 { "select-cursor-extend", HandleKeyboardSelectExtend }, 266 { "select-cursor-start", HandleKeyboardSelectStart }, 267 { "select-end", HandleSelectEnd }, 268 { "select-extend", HandleSelectExtend }, 269 { "select-set", HandleSelectSet }, 270 { "select-start", HandleSelectStart }, 271 { "send-signal", HandleSendSignal }, 272 { "set-8-bit-control", Handle8BitControl }, 273 { "set-allow132", HandleAllow132 }, 274 { "set-altscreen", HandleAltScreen }, 275 { "set-appcursor", HandleAppCursor }, 276 { "set-appkeypad", HandleAppKeypad }, 277 { "set-autolinefeed", HandleAutoLineFeed }, 278 { "set-autowrap", HandleAutoWrap }, 279 { "set-backarrow", HandleBackarrow }, 280 { "set-bellIsUrgent", HandleBellIsUrgent }, 281 { "set-cursesemul", HandleCursesEmul }, 282 { "set-jumpscroll", HandleJumpscroll }, 283 { "set-keep-clipboard", HandleKeepClipboard }, 284 { "set-keep-selection", HandleKeepSelection }, 285 { "set-marginbell", HandleMarginBell }, 286 { "set-old-function-keys", HandleOldFunctionKeys }, 287 { "set-pop-on-bell", HandleSetPopOnBell }, 288 { "set-reverse-video", HandleReverseVideo }, 289 { "set-reversewrap", HandleReverseWrap }, 290 { "set-scroll-on-key", HandleScrollKey }, 291 { "set-scroll-on-tty-output", HandleScrollTtyOutput }, 292 { "set-scrollbar", HandleScrollbar }, 293 { "set-select", HandleSetSelect }, 294 { "set-sun-keyboard", HandleSunKeyboard }, 295 { "set-titeInhibit", HandleTiteInhibit }, 296 { "set-visual-bell", HandleSetVisualBell }, 297 { "set-vt-font", HandleSetFont }, 298 { "soft-reset", HandleSoftReset }, 299 { "start-cursor-extend", HandleKeyboardStartExtend }, 300 { "start-extend", HandleStartExtend }, 301 { "string", HandleStringEvent }, 302 { "vi-button", ViButton }, 303 { "visual-bell", HandleVisualBell }, 304#ifdef ALLOWLOGGING 305 { "set-logging", HandleLogging }, 306#endif 307#if OPT_ALLOW_XXX_OPS 308 { "allow-color-ops", HandleAllowColorOps }, 309 { "allow-font-ops", HandleAllowFontOps }, 310 { "allow-mouse-ops", HandleAllowMouseOps }, 311 { "allow-tcap-ops", HandleAllowTcapOps }, 312 { "allow-title-ops", HandleAllowTitleOps }, 313 { "allow-window-ops", HandleAllowWindowOps }, 314#endif 315#if OPT_BLINK_CURS 316 { "set-cursorblink", HandleCursorBlink }, 317#endif 318#if OPT_BOX_CHARS 319 { "set-font-linedrawing", HandleFontBoxChars }, 320 { "set-font-packed", HandleFontPacked }, 321#endif 322#if OPT_DABBREV 323 { "dabbrev-expand", HandleDabbrevExpand }, 324#endif 325#if OPT_DEC_CHRSET 326 { "set-font-doublesize", HandleFontDoublesize }, 327#endif 328#if OPT_DEC_SOFTFONT 329 { "set-font-loading", HandleFontLoading }, 330#endif 331#if OPT_SCREEN_DUMPS 332 { "dump-html", HandleDumpHtml }, 333 { "dump-svg", HandleDumpSvg }, 334#endif 335#if OPT_EXEC_XTERM 336 { "spawn-new-terminal", HandleSpawnTerminal }, 337#endif 338#if OPT_HP_FUNC_KEYS 339 { "set-hp-function-keys", HandleHpFunctionKeys }, 340#endif 341#if OPT_LOAD_VTFONTS 342 { "load-vt-fonts", HandleLoadVTFonts }, 343#endif 344#if OPT_MAXIMIZE 345 { "deiconify", HandleDeIconify }, 346 { "fullscreen", HandleFullscreen }, 347 { "iconify", HandleIconify }, 348 { "maximize", HandleMaximize }, 349 { "restore", HandleRestoreSize }, 350#endif 351#if OPT_NUM_LOCK 352 { "alt-sends-escape", HandleAltEsc }, 353 { "meta-sends-escape", HandleMetaEsc }, 354 { "set-num-lock", HandleNumLock }, 355#endif 356#if OPT_READLINE 357 { "readline-button", ReadLineButton }, 358#endif 359#if OPT_RENDERFONT 360 { "set-render-font", HandleRenderFont }, 361#endif 362#if OPT_SCO_FUNC_KEYS 363 { "set-sco-function-keys", HandleScoFunctionKeys }, 364#endif 365#if OPT_SCROLL_LOCK 366 { "scroll-lock", HandleScrollLock }, 367#endif 368#if OPT_SELECTION_OPS 369 { "exec-formatted", HandleExecFormatted }, 370 { "exec-selectable", HandleExecSelectable }, 371 { "insert-formatted", HandleInsertFormatted }, 372 { "insert-selectable", HandleInsertSelectable }, 373#endif 374#if OPT_SHIFT_FONTS 375 { "larger-vt-font", HandleLargerFont }, 376 { "smaller-vt-font", HandleSmallerFont }, 377#endif 378#if OPT_SIXEL_GRAPHICS 379 { "set-sixel-scrolling", HandleSixelScrolling }, 380#endif 381#if OPT_GRAPHICS 382 { "set-private-colors", HandleSetPrivateColorRegisters }, 383#endif 384#if OPT_SUN_FUNC_KEYS 385 { "set-sun-function-keys", HandleSunFunctionKeys }, 386#endif 387#if OPT_TEK4014 388 { "set-terminal-type", HandleSetTerminalType }, 389 { "set-visibility", HandleVisibility }, 390 { "set-tek-text", HandleSetTekText }, 391 { "tek-page", HandleTekPage }, 392 { "tek-reset", HandleTekReset }, 393 { "tek-copy", HandleTekCopy }, 394#endif 395#if OPT_TOOLBAR 396 { "set-toolbar", HandleToolbar }, 397#endif 398#if OPT_WIDE_CHARS 399 { "set-utf8-mode", HandleUTF8Mode }, 400 { "set-utf8-fonts", HandleUTF8Fonts }, 401 { "set-utf8-title", HandleUTF8Title }, 402#endif 403}; 404/* *INDENT-ON* */ 405 406#define SPS screen.printer_state 407 408static XtResource xterm_resources[] = 409{ 410 Bres(XtNallowPasteControls, XtCAllowPasteControls, 411 screen.allowPasteControl0, False), 412 Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False), 413 Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR), 414 Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT), 415 Bres(XtNallowMouseOps, XtCAllowMouseOps, screen.allowMouseOp0, DEF_ALLOW_MOUSE), 416 Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP), 417 Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE), 418 Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW), 419 Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False), 420 Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, DEF_ALT_SENDS_ESC), 421 Bres(XtNallowBoldFonts, XtCAllowBoldFonts, screen.allowBoldFonts, True), 422 Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False), 423 Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False), 424 Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False), 425 Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False), 426 Bres(XtNalternateScroll, XtCScrollCond, screen.alternateScroll, False), 427 Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True), 428 Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False), 429 Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False), 430 Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, DEF_BACKARO_BS), 431 Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False), 432 Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True), 433 Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True), 434 Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False), 435 Bres(XtNc132, XtCC132, screen.c132, False), 436 Bres(XtNcdXtraScroll, XtCCdXtraScroll, misc.cdXtraScroll, False), 437 Bres(XtNcurses, XtCCurses, screen.curses, False), 438 Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True), 439 Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine, 440 screen.cutToBeginningOfLine, True), 441 Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL), 442 Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True), 443 Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False), 444 Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True), 445 Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True), 446 Bres(XtNeraseSavedLines, XtCEraseSavedLines, screen.eraseSavedLines0, True), 447 Bres(XtNhighlightSelection, XtCHighlightSelection, 448 screen.highlight_selection, False), 449 Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False), 450 Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False), 451 Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True), 452 Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False), 453 Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True), 454 Bres(XtNkeepClipboard, XtCKeepClipboard, screen.keepClipboard, False), 455 Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True), 456 Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False), 457 Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False), 458 Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, DEF_META_SENDS_ESC), 459 Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False), 460 Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False), 461 Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False), 462 Bres(XtNprinterAutoClose, XtCPrinterAutoClose, SPS.printer_autoclose, False), 463 Bres(XtNprinterExtent, XtCPrinterExtent, SPS.printer_extent, False), 464 Bres(XtNprinterFormFeed, XtCPrinterFormFeed, SPS.printer_formfeed, False), 465 Bres(XtNprinterNewLine, XtCPrinterNewLine, SPS.printer_newline, True), 466 Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False), 467 Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False), 468 Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False), 469 Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False), 470 Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False), 471 Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True), 472 Bres(XtNselectToClipboard, XtCSelectToClipboard, 473 screen.selectToClipboard, False), 474 Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False), 475 Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False), 476 Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False), 477 Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False), 478 Bres(XtNunderLine, XtCUnderLine, screen.underline, True), 479 Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False), 480 Bres(XtNvisualBellLine, XtCVisualBellLine, screen.flash_line, False), 481 482 Dres(XtNscaleHeight, XtCScaleHeight, screen.scale_height, "1.0"), 483 484 Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC), 485 Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource), 486 Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER), 487 Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1), 488 Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME), 489 Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL), 490 Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE), 491 Ires(XtNprinterControlMode, XtCPrinterControlMode, 492 SPS.printer_controlmode, 0), 493 Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES), 494 Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100), 495 Ires(XtNsaveLines, XtCSaveLines, screen.savelines, SAVELINES), 496 Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1), 497 Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, SCROLLLINES), 498 499 Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL), 500 Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL), 501 Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL), 502 Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL), 503 Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL), 504 Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL), 505 Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL), 506 507 Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""), 508 Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT), 509 Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL), 510 Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID), 511 Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"), 512 Sres(XtNdisallowedColorOps, XtCDisallowedColorOps, 513 screen.disallowedColorOps, DEF_DISALLOWED_COLOR), 514 Sres(XtNdisallowedFontOps, XtCDisallowedFontOps, 515 screen.disallowedFontOps, DEF_DISALLOWED_FONT), 516 Sres(XtNdisallowedMouseOps, XtCDisallowedMouseOps, 517 screen.disallowedMouseOps, DEF_DISALLOWED_MOUSE), 518 Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps, 519 screen.disallowedTcapOps, DEF_DISALLOWED_TCAP), 520 Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps, 521 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW), 522 Sres(XtNeightBitMeta, XtCEightBitMeta, screen.eight_bit_meta_s, DEF_8BIT_META), 523 Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes, 524 screen.eightbit_select_types, NULL), 525 Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT), 526 Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL), 527 Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT), 528 Sres(XtNprinterCommand, XtCPrinterCommand, SPS.printer_command, ""), 529 Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL), 530 531 Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground), 532 Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground), 533 Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground), 534 Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground), 535 Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground), 536 537 {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity), 538 XtOffsetOf(XtermWidgetRec, misc.resizeGravity), 539 XtRImmediate, (XtPointer) SouthWestGravity}, 540 541 {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor), 542 XtOffsetOf(XtermWidgetRec, screen.pointer_cursor), 543 XtRString, (XtPointer) "xterm"}, 544 545#ifdef ALLOWLOGGING 546 Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False), 547 Bres(XtNlogging, XtCLogging, misc.log_on, False), 548 Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL), 549#endif 550 551#ifndef NO_ACTIVE_ICON 552 Sres("activeIcon", "ActiveIcon", misc.active_icon_s, "default"), 553 Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2), 554 Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"), 555 Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground), 556#endif /* NO_ACTIVE_ICON */ 557 558#if OPT_BLINK_CURS 559 Bres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink, False), 560#endif 561 Bres(XtNcursorUnderLine, XtCCursorUnderLine, screen.cursor_underline, False), 562 563#if OPT_BLINK_TEXT 564 Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD), 565#endif 566 567#if OPT_BLINK_CURS || OPT_BLINK_TEXT 568 Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600), 569 Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300), 570#endif 571 572#if OPT_BOX_CHARS 573 Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False), 574 Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True), 575 Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False), 576 Bres(XtNassumeAllChars, XtCAssumeAllChars, screen.assume_all_chars, True), 577#endif 578 579#if OPT_BROKEN_OSC 580 Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True), 581#endif 582 583#if OPT_BROKEN_ST 584 Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, False), 585#endif 586 587#if OPT_C1_PRINT 588 Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False), 589#endif 590 591#if OPT_CLIP_BOLD 592 Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True), 593#endif 594 595#if OPT_DEC_CHRSET 596 Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True), 597 Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET), 598#endif 599 600#if OPT_HIGHLIGHT_COLOR 601 Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground), 602 Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground), 603 Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True), 604 Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe), 605#endif /* OPT_HIGHLIGHT_COLOR */ 606 607#if OPT_INPUT_METHOD 608 Bres(XtNopenIm, XtCOpenIm, misc.open_im, True), 609 Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL), 610 Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type, 611 "OverTheSpot,Root"), 612 Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3), 613#endif 614 615#if OPT_ISO_COLORS 616 Bres(XtNboldColors, XtCColorMode, screen.boldColors, True), 617 Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0), 618 Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE), 619 620 Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False), 621 Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False), 622 Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False), 623 Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False), 624 Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False), 625 Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False), 626#if OPT_WIDE_ATTRS 627 Bres(XtNcolorITMode, XtCColorAttrMode, screen.colorITMode, False), 628#endif 629 630 COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")), 631 COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")), 632 COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")), 633 COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")), 634 COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)), 635 COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")), 636 COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")), 637 COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")), 638 COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")), 639 COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")), 640 COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")), 641 COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")), 642 COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)), 643 COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")), 644 COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")), 645 COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")), 646 COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)), 647 COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)), 648 COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)), 649 COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)), 650 651#if OPT_WIDE_ATTRS 652 COLOR_RES("IT", screen.Acolors[COLOR_IT], DFT_COLOR(XtDefaultForeground)), 653#endif 654 655#if !OPT_COLOR_RES2 656#if OPT_256_COLORS 657# include <256colres.h> 658#elif OPT_88_COLORS 659# include <88colres.h> 660#endif 661#endif /* !OPT_COLOR_RES2 */ 662 663#endif /* OPT_ISO_COLORS */ 664 665 CLICK_RES("2", screen.onClick[1], "word"), 666 CLICK_RES("3", screen.onClick[2], "line"), 667 CLICK_RES("4", screen.onClick[3], 0), 668 CLICK_RES("5", screen.onClick[4], 0), 669 670#if OPT_MOD_FKEYS 671 Ires(XtNmodifyKeyboard, XtCModifyKeyboard, 672 keyboard.modify_1st.allow_keys, 0), 673 Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys, 674 keyboard.modify_1st.cursor_keys, 2), 675 Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys, 676 keyboard.modify_1st.function_keys, 2), 677 Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys, 678 keyboard.modify_1st.keypad_keys, 0), 679 Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys, 680 keyboard.modify_1st.other_keys, 0), 681 Ires(XtNmodifyStringKeys, XtCModifyStringKeys, 682 keyboard.modify_1st.string_keys, 0), 683 Ires(XtNformatOtherKeys, XtCFormatOtherKeys, 684 keyboard.format_keys, 0), 685#endif 686 687#if OPT_NUM_LOCK 688 Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False), 689 Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True), 690#endif 691 692#if OPT_PRINT_COLORS 693 Ires(XtNprintAttributes, XtCPrintAttributes, SPS.print_attributes, 1), 694#endif 695 696#if OPT_REGIS_GRAPHICS 697 Sres(XtNregisDefaultFont, XtCRegisDefaultFont, 698 screen.graphics_regis_default_font, ""), 699 Sres(XtNregisScreenSize, XtCRegisScreenSize, 700 screen.graphics_regis_screensize, "auto"), 701#endif 702 703#if OPT_GRAPHICS 704 Sres(XtNmaxGraphicSize, XtCMaxGraphicSize, screen.graphics_max_size, 705 "1000x1000"), 706#endif 707 708#if OPT_SHIFT_FONTS 709 Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True), 710#endif 711 712#if OPT_SIXEL_GRAPHICS 713 Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, True), 714 Bres(XtNsixelScrollsRight, XtCSixelScrollsRight, 715 screen.sixel_scrolls_right, False), 716#endif 717 718#if OPT_GRAPHICS 719 Ires(XtNnumColorRegisters, XtCNumColorRegisters, 720 screen.numcolorregisters, 0), 721 Bres(XtNprivateColorRegisters, XtCPrivateColorRegisters, 722 screen.privatecolorregisters, True), 723#endif 724 725#if OPT_SUNPC_KBD 726 Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10), 727#endif 728 729#if OPT_TEK4014 730 Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False), 731 Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False), 732 Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False), 733#endif 734 735#if OPT_TOOLBAR 736 Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0), 737 Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25), 738#endif 739 740#if OPT_WIDE_CHARS 741 Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False), 742 Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False), 743 Bres(XtNprecompose, XtCPrecompose, screen.normalized_c, True), 744 Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False), 745 Bres(XtNutf8Title, XtCUtf8Title, screen.utf8_title, False), 746 Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True), 747 Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False), 748 Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2), 749 Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 655), 750 Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 65536), 751 Sres(XtNutf8, XtCUtf8, screen.utf8_mode_s, "default"), 752 Sres(XtNutf8Fonts, XtCUtf8Fonts, screen.utf8_fonts_s, "default"), 753 Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT), 754 Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT), 755 Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL), 756#endif 757 758#if OPT_LUIT_PROG 759 Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"), 760 Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER), 761#endif 762 763#if OPT_INPUT_METHOD 764 Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT), 765#endif 766 767#if OPT_SCROLL_LOCK 768 Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False), 769#endif 770 771 /* these are used only for testing ncurses, not in the manual page */ 772#if OPT_XMC_GLITCH 773 Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False), 774 Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True), 775 Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1), 776 Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0), 777#endif 778 779#ifdef SCROLLBAR_RIGHT 780 Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False), 781#endif 782 783#if OPT_RENDERFONT 784#define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0") 785 RES_FACESIZE(1), 786 RES_FACESIZE(2), 787 RES_FACESIZE(3), 788 RES_FACESIZE(4), 789 RES_FACESIZE(5), 790 RES_FACESIZE(6), 791 Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE), 792 Sres(XtNfaceName, XtCFaceName, misc.default_xft.f_n, DEFFACENAME), 793 Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"), 794#if OPT_RENDERWIDE 795 Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.default_xft.f_w, DEFFACENAME), 796#endif 797#endif 798}; 799 800static Boolean VTSetValues(Widget cur, Widget request, Widget new_arg, 801 ArgList args, Cardinal *num_args); 802static void VTClassInit(void); 803static void VTDestroy(Widget w); 804static void VTExpose(Widget w, XEvent *event, Region region); 805static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args, 806 Cardinal *num_args); 807static void VTRealize(Widget w, XtValueMask * valuemask, 808 XSetWindowAttributes * values); 809static void VTResize(Widget w); 810 811#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 812static void VTInitI18N(XtermWidget); 813#endif 814 815#ifdef VMS 816globaldef { 817 "xtermclassrec" 818} noshare 819 820#else 821static 822#endif /* VMS */ 823WidgetClassRec xtermClassRec = 824{ 825 { 826 /* core_class fields */ 827 (WidgetClass) & widgetClassRec, /* superclass */ 828 "VT100", /* class_name */ 829 sizeof(XtermWidgetRec), /* widget_size */ 830 VTClassInit, /* class_initialize */ 831 NULL, /* class_part_initialize */ 832 False, /* class_inited */ 833 VTInitialize, /* initialize */ 834 NULL, /* initialize_hook */ 835 VTRealize, /* realize */ 836 actionsList, /* actions */ 837 XtNumber(actionsList), /* num_actions */ 838 xterm_resources, /* resources */ 839 XtNumber(xterm_resources), /* num_resources */ 840 NULLQUARK, /* xrm_class */ 841 True, /* compress_motion */ 842 False, /* compress_exposure */ 843 True, /* compress_enterleave */ 844 False, /* visible_interest */ 845 VTDestroy, /* destroy */ 846 VTResize, /* resize */ 847 VTExpose, /* expose */ 848 VTSetValues, /* set_values */ 849 NULL, /* set_values_hook */ 850 XtInheritSetValuesAlmost, /* set_values_almost */ 851 NULL, /* get_values_hook */ 852 NULL, /* accept_focus */ 853 XtVersion, /* version */ 854 NULL, /* callback_offsets */ 855 0, /* tm_table */ 856 XtInheritQueryGeometry, /* query_geometry */ 857 XtInheritDisplayAccelerator, /* display_accelerator */ 858 NULL /* extension */ 859 } 860}; 861 862#ifdef VMS 863globaldef { 864 "xtermwidgetclass" 865} 866noshare 867#endif /* VMS */ 868WidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec; 869 870/* 871 * Add input-actions for widgets that are overlooked (scrollbar and toolbar): 872 * 873 * a) Sometimes the scrollbar passes through translations, sometimes it 874 * doesn't. We add the KeyPress translations here, just to be sure. 875 * b) In the normal (non-toolbar) configuration, the xterm widget covers 876 * almost all of the window. With a toolbar, there's a relatively 877 * large area that the user would expect to enter keystrokes since the 878 * program can get the focus. 879 */ 880void 881xtermAddInput(Widget w) 882{ 883 /* *INDENT-OFF* */ 884 XtActionsRec input_actions[] = { 885 { "insert", HandleKeyPressed }, /* alias */ 886 { "insert-eight-bit", HandleEightBitKeyPressed }, 887 { "insert-seven-bit", HandleKeyPressed }, 888 { "secure", HandleSecure }, 889 { "string", HandleStringEvent }, 890 { "scroll-back", HandleScrollBack }, 891 { "scroll-forw", HandleScrollForward }, 892 { "select-cursor-end", HandleKeyboardSelectEnd }, 893 { "select-cursor-extend", HandleKeyboardSelectExtend }, 894 { "select-cursor-start", HandleKeyboardSelectStart }, 895 { "insert-selection", HandleInsertSelection }, 896 { "select-start", HandleSelectStart }, 897 { "select-extend", HandleSelectExtend }, 898 { "start-extend", HandleStartExtend }, 899 { "select-end", HandleSelectEnd }, 900 { "clear-saved-lines", HandleClearSavedLines }, 901 { "popup-menu", HandlePopupMenu }, 902 { "bell", HandleBell }, 903 { "ignore", HandleIgnore }, 904#if OPT_DABBREV 905 { "dabbrev-expand", HandleDabbrevExpand }, 906#endif 907#if OPT_MAXIMIZE 908 { "fullscreen", HandleFullscreen }, 909#endif 910#if OPT_SCROLL_LOCK 911 { "scroll-lock", HandleScrollLock }, 912#endif 913#if OPT_SHIFT_FONTS 914 { "larger-vt-font", HandleLargerFont }, 915 { "smaller-vt-font", HandleSmallerFont }, 916#endif 917 }; 918 /* *INDENT-ON* */ 919 920 TRACE_TRANS("BEFORE", w); 921 XtAppAddActions(app_con, input_actions, XtNumber(input_actions)); 922 XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations)); 923 TRACE_TRANS("AFTER:", w); 924 925#if OPT_EXTRA_PASTE 926 if (term && term->keyboard.extra_translations) 927 XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations)); 928#endif 929} 930 931#if OPT_ISO_COLORS 932#ifdef EXP_BOGUS_FG 933static Bool 934CheckBogusForeground(TScreen *screen, const char *tag) 935{ 936 int row = -1, col = -1, pass; 937 Bool isClear = True; 938 939 (void) tag; 940 for (pass = 0; pass < 2; ++pass) { 941 row = screen->cur_row; 942 for (; isClear && (row <= screen->max_row); ++row) { 943 CLineData *ld = getLineData(screen, row); 944 945 if (ld != 0) { 946 IAttr *attribs = ld->attribs; 947 948 col = (row == screen->cur_row) ? screen->cur_col : 0; 949 for (; isClear && (col <= screen->max_col); ++col) { 950 unsigned flags = attribs[col]; 951 if (pass) { 952 flags &= ~FG_COLOR; 953 attribs[col] = (IAttr) flags; 954 } else if ((flags & BG_COLOR)) { 955 isClear = False; 956 } else if ((flags & FG_COLOR)) { 957 unsigned ch = ld->charData[col]; 958 isClear = ((ch == ' ') || (ch == 0)); 959 } else { 960 isClear = False; 961 } 962 } 963 } 964 } 965 } 966 TRACE(("%s checked %d,%d to %d,%d %s pass %d\n", 967 tag, screen->cur_row, screen->cur_col, 968 row, col, 969 isClear && pass ? "cleared" : "unchanged", 970 pass)); 971 972 return isClear; 973} 974#endif 975 976/* 977 * The terminal's foreground and background colors are set via two mechanisms: 978 * text (cur_foreground, cur_background values that are passed down to 979 * XDrawImageString and XDrawString) 980 * area (X11 graphics context used in XClearArea and XFillRectangle) 981 */ 982void 983SGR_Foreground(XtermWidget xw, int color) 984{ 985 TScreen *screen = TScreenOf(xw); 986 Pixel fg; 987 988 if (color >= 0) { 989 UIntSet(xw->flags, FG_COLOR); 990 } else { 991 UIntClr(xw->flags, FG_COLOR); 992 } 993 fg = getXtermForeground(xw, xw->flags, color); 994 xw->cur_foreground = color; 995 996 setCgsFore(xw, WhichVWin(screen), gcNorm, fg); 997 setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg); 998 999 setCgsFore(xw, WhichVWin(screen), gcBold, fg); 1000 setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg); 1001 1002#ifdef EXP_BOGUS_FG 1003 /* 1004 * If we've just turned off the foreground color, check for blank cells 1005 * which have no background color, but do have foreground color. This 1006 * could happen due to setting the foreground color just before scrolling. 1007 * 1008 * Those cells look uncolored, but will confuse ShowCursor(), which looks 1009 * for the colors in the current cell, and will see the foreground color. 1010 * In that case, remove the foreground color from the blank cells. 1011 */ 1012 if (color < 0) { 1013 CheckBogusForeground(screen, "SGR_Foreground"); 1014 } 1015#endif 1016} 1017 1018void 1019SGR_Background(XtermWidget xw, int color) 1020{ 1021 TScreen *screen = TScreenOf(xw); 1022 Pixel bg; 1023 1024 /* 1025 * An indexing operation may have set screen->scroll_amt, which would 1026 * normally result in calling FlushScroll() in WriteText(). However, 1027 * if we're changing the background color now, then the new value 1028 * should not apply to the pending blank lines. 1029 */ 1030 if (screen->scroll_amt && (color != xw->cur_background)) 1031 FlushScroll(xw); 1032 1033 if (color >= 0) { 1034 UIntSet(xw->flags, BG_COLOR); 1035 } else { 1036 UIntClr(xw->flags, BG_COLOR); 1037 } 1038 bg = getXtermBackground(xw, xw->flags, color); 1039 xw->cur_background = color; 1040 1041 setCgsBack(xw, WhichVWin(screen), gcNorm, bg); 1042 setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg); 1043 1044 setCgsBack(xw, WhichVWin(screen), gcBold, bg); 1045 setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg); 1046} 1047 1048/* Invoked after updating bold/underline flags, computes the extended color 1049 * index to use for foreground. (See also 'extract_fg()'). 1050 */ 1051static void 1052setExtendedFG(XtermWidget xw) 1053{ 1054 int fg = xw->sgr_foreground; 1055 1056 if (TScreenOf(xw)->colorAttrMode 1057 || (fg < 0)) { 1058 fg = MapToColorMode(fg, TScreenOf(xw), xw->flags); 1059 } 1060 1061 /* This implements the IBM PC-style convention of 8-colors, with one 1062 * bit for bold, thus mapping the 0-7 codes to 8-15. It won't make 1063 * much sense for 16-color applications, but we keep it to retain 1064 * compatiblity with ANSI-color applications. 1065 */ 1066#if OPT_PC_COLORS /* XXXJTL should be settable at runtime (resource or OSC?) */ 1067 if (TScreenOf(xw)->boldColors 1068 && (!xw->sgr_extended) 1069 && (fg >= 0) 1070 && (fg < 8) 1071 && (xw->flags & BOLD)) 1072 fg |= 8; 1073#endif 1074 1075 SGR_Foreground(xw, fg); 1076} 1077 1078/* Invoked after updating inverse flag, computes the extended color 1079 * index to use for background. (See also 'extract_bg()'). 1080 */ 1081static void 1082setExtendedBG(XtermWidget xw) 1083{ 1084 int bg = xw->sgr_background; 1085 1086 if (TScreenOf(xw)->colorAttrMode 1087 || (bg < 0)) { 1088 if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE)) 1089 bg = COLOR_RV; 1090 } 1091 1092 SGR_Background(xw, bg); 1093} 1094 1095static void 1096reset_SGR_Foreground(XtermWidget xw) 1097{ 1098 xw->sgr_foreground = -1; 1099 xw->sgr_extended = False; 1100 setExtendedFG(xw); 1101} 1102 1103static void 1104reset_SGR_Background(XtermWidget xw) 1105{ 1106 xw->sgr_background = -1; 1107 setExtendedBG(xw); 1108} 1109 1110static void 1111reset_SGR_Colors(XtermWidget xw) 1112{ 1113 reset_SGR_Foreground(xw); 1114 reset_SGR_Background(xw); 1115} 1116#endif /* OPT_ISO_COLORS */ 1117 1118#if OPT_WIDE_ATTRS 1119/* 1120 * Call this before changing the state of ATR_ITALIC, to update the GC fonts. 1121 */ 1122static void 1123setItalicFont(XtermWidget xw, Bool enable) 1124{ 1125 if (enable) { 1126 if ((xw->flags & ATR_ITALIC) == 0) { 1127 xtermLoadItalics(xw); 1128 TRACE(("setItalicFont: enabling Italics\n")); 1129 xtermUpdateFontGCs(xw, True); 1130 } 1131 } else if ((xw->flags & ATR_ITALIC) != 0) { 1132 TRACE(("setItalicFont: disabling Italics\n")); 1133 xtermUpdateFontGCs(xw, False); 1134 } 1135} 1136#endif 1137 1138void 1139resetCharsets(TScreen *screen) 1140{ 1141 TRACE(("resetCharsets\n")); 1142 1143 screen->gsets[0] = nrc_ASCII; 1144 screen->gsets[1] = nrc_ASCII; 1145 screen->gsets[2] = nrc_ASCII; 1146 screen->gsets[3] = nrc_ASCII; 1147 1148 screen->curgl = 0; /* G0 => GL. */ 1149 screen->curgr = 2; /* G2 => GR. */ 1150 screen->curss = 0; /* No single shift. */ 1151 1152#if OPT_VT52_MODE 1153 if (screen->vtXX_level == 0) 1154 screen->gsets[1] = nrc_DEC_Spec_Graphic; /* Graphics */ 1155#endif 1156} 1157 1158static void 1159modified_DECNRCM(XtermWidget xw) 1160{ 1161#if OPT_WIDE_CHARS 1162 TScreen *screen = TScreenOf(xw); 1163 if (screen->wide_chars && (screen->utf8_mode || screen->utf8_nrc_mode)) { 1164 int enabled = ((xw->flags & NATIONAL) != 0); 1165 int modefix; 1166 EXCHANGE(screen->utf8_nrc_mode, screen->utf8_mode, modefix); 1167 switchPtyData(screen, !enabled); 1168 TRACE(("UTF8 mode temporarily %s\n", enabled ? "ON" : "OFF")); 1169 } 1170#endif 1171} 1172 1173/* 1174 * VT300 and up support three ANSI conformance levels, defined according to 1175 * the dpANSI X3.134.1 standard. DEC's manuals equate levels 1 and 2, and 1176 * are unclear. This code is written based on the manuals. 1177 */ 1178static void 1179set_ansi_conformance(TScreen *screen, int level) 1180{ 1181 TRACE(("set_ansi_conformance(%d) dec_level %d:%d, ansi_level %d\n", 1182 level, 1183 screen->vtXX_level * 100, 1184 screen->terminal_id, 1185 screen->ansi_level)); 1186 if (screen->vtXX_level >= 3) { 1187 switch (screen->ansi_level = level) { 1188 case 1: 1189 /* FALLTHRU */ 1190 case 2: 1191 screen->gsets[0] = nrc_ASCII; /* G0 is ASCII */ 1192 screen->gsets[1] = nrc_ASCII; /* G1 is ISO Latin-1 */ 1193 screen->curgl = 0; 1194 screen->curgr = 1; 1195 break; 1196 case 3: 1197 screen->gsets[0] = nrc_ASCII; /* G0 is ASCII */ 1198 screen->curgl = 0; 1199 break; 1200 } 1201 } 1202} 1203 1204/* 1205 * Set scrolling margins. VTxxx terminals require that the top/bottom are 1206 * different, so we have at least two lines in the scrolling region. 1207 */ 1208void 1209set_tb_margins(TScreen *screen, int top, int bottom) 1210{ 1211 TRACE(("set_tb_margins %d..%d, prior %d..%d\n", 1212 top, bottom, 1213 screen->top_marg, 1214 screen->bot_marg)); 1215 if (bottom > top) { 1216 screen->top_marg = top; 1217 screen->bot_marg = bottom; 1218 } 1219 if (screen->top_marg > screen->max_row) 1220 screen->top_marg = screen->max_row; 1221 if (screen->bot_marg > screen->max_row) 1222 screen->bot_marg = screen->max_row; 1223} 1224 1225void 1226set_lr_margins(TScreen *screen, int left, int right) 1227{ 1228 TRACE(("set_lr_margins %d..%d, prior %d..%d\n", 1229 left, right, 1230 screen->lft_marg, 1231 screen->rgt_marg)); 1232 if (right > left) { 1233 screen->lft_marg = left; 1234 screen->rgt_marg = right; 1235 } 1236 if (screen->lft_marg > screen->max_col) 1237 screen->lft_marg = screen->max_col; 1238 if (screen->rgt_marg > screen->max_col) 1239 screen->rgt_marg = screen->max_col; 1240} 1241 1242#define reset_tb_margins(screen) set_tb_margins(screen, 0, screen->max_row) 1243#define reset_lr_margins(screen) set_lr_margins(screen, 0, screen->max_col) 1244 1245static void 1246reset_margins(TScreen *screen) 1247{ 1248 reset_tb_margins(screen); 1249 reset_lr_margins(screen); 1250} 1251 1252void 1253set_max_col(TScreen *screen, int cols) 1254{ 1255 TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col)); 1256 if (cols < 0) 1257 cols = 0; 1258 screen->max_col = cols; 1259} 1260 1261void 1262set_max_row(TScreen *screen, int rows) 1263{ 1264 TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row)); 1265 if (rows < 0) 1266 rows = 0; 1267 screen->max_row = rows; 1268} 1269 1270#if OPT_MOD_FKEYS 1271static void 1272set_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled) 1273{ 1274#define SET_MOD_FKEYS(field) \ 1275 xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \ 1276 ? xw->keyboard.modify_1st.field \ 1277 : what; \ 1278 TRACE(("set modify_now.%s to %d\n", #field, \ 1279 xw->keyboard.modify_now.field)); 1280 1281 switch (which) { 1282 case 0: 1283 SET_MOD_FKEYS(allow_keys); 1284 break; 1285 case 1: 1286 SET_MOD_FKEYS(cursor_keys); 1287 break; 1288 case 2: 1289 SET_MOD_FKEYS(function_keys); 1290 break; 1291 case 3: 1292 SET_MOD_FKEYS(keypad_keys); 1293 break; 1294 case 4: 1295 SET_MOD_FKEYS(other_keys); 1296 break; 1297 case 5: 1298 SET_MOD_FKEYS(string_keys); 1299 break; 1300 } 1301} 1302#endif /* OPT_MOD_FKEYS */ 1303 1304#if OPT_TRACE 1305#define DATA(name) { name, #name } 1306static const struct { 1307 Const PARSE_T *table; 1308 const char *name; 1309} all_tables[] = { 1310 1311 DATA(ansi_table) 1312 ,DATA(cigtable) 1313 ,DATA(csi2_table) 1314 ,DATA(csi_ex_table) 1315 ,DATA(csi_quo_table) 1316 ,DATA(csi_table) 1317 ,DATA(dec2_table) 1318 ,DATA(dec3_table) 1319 ,DATA(dec_table) 1320 ,DATA(eigtable) 1321 ,DATA(esc_sp_table) 1322 ,DATA(esc_table) 1323 ,DATA(scrtable) 1324 ,DATA(scs96table) 1325 ,DATA(scstable) 1326 ,DATA(sos_table) 1327#if OPT_BLINK_CURS 1328 ,DATA(csi_sp_table) 1329#endif 1330#if OPT_DEC_LOCATOR 1331 ,DATA(csi_tick_table) 1332#endif 1333#if OPT_DEC_RECTOPS 1334 ,DATA(csi_dollar_table) 1335 ,DATA(csi_star_table) 1336 ,DATA(csi_dec_dollar_table) 1337#endif 1338#if OPT_WIDE_CHARS 1339 ,DATA(esc_pct_table) 1340 ,DATA(scs_pct_table) 1341#endif 1342#if OPT_VT52_MODE 1343 ,DATA(vt52_table) 1344 ,DATA(vt52_esc_table) 1345 ,DATA(vt52_ignore_table) 1346#endif 1347#undef DATA 1348}; 1349 1350#define WHICH_TABLE(name) if (table == name) result = #name 1351static const char * 1352which_table(Const PARSE_T * table) 1353{ 1354 const char *result = "?"; 1355 Cardinal n; 1356 for (n = 0; n < XtNumber(all_tables); ++n) { 1357 if (table == all_tables[n].table) { 1358 result = all_tables[n].name; 1359 break; 1360 } 1361 } 1362 1363 return result; 1364} 1365 1366static void 1367check_tables(void) 1368{ 1369 Cardinal n; 1370 int ch; 1371 1372 TRACE(("** check_tables\n")); 1373 for (n = 0; n < XtNumber(all_tables); ++n) { 1374 Const PARSE_T *table = all_tables[n].table; 1375 TRACE(("*** %s\n", all_tables[n].name)); 1376 /* 1377 * Most of the tables should use the same codes in 0..31, 128..159 1378 * as the "ansi" table. 1379 */ 1380 if (strncmp(all_tables[n].name, "ansi", 4) && 1381 strncmp(all_tables[n].name, "sos_", 4) && 1382 strncmp(all_tables[n].name, "vt52", 4)) { 1383 for (ch = 0; ch < 32; ++ch) { 1384 int c1 = ch + 128; 1385 PARSE_T st_l = table[ch]; 1386 PARSE_T st_r = table[c1]; 1387 if (st_l != ansi_table[ch]) { 1388 TRACE((" %3d: %d vs %d\n", ch, st_l, ansi_table[ch])); 1389 } 1390 if (st_r != ansi_table[c1]) { 1391 TRACE((" %3d: %d vs %d\n", c1, st_r, ansi_table[c1])); 1392 } 1393 } 1394 } 1395 /* 1396 * All of the tables should have their GL/GR parts encoded the same. 1397 */ 1398 for (ch = 32; ch < 127; ++ch) { 1399 PARSE_T st_l = table[ch]; 1400 PARSE_T st_r = table[ch + 128]; 1401 if (st_l != st_r) { 1402 if (st_r == CASE_IGNORE && 1403 !strncmp(all_tables[n].name, "vt52", 4)) { 1404 ; 1405 } else { 1406 TRACE((" %3d: %d vs %d\n", ch, st_l, st_r)); 1407 } 1408 } 1409 } 1410 } 1411} 1412#endif 1413 1414#if OPT_TRACE > 0 1415static void 1416dump_params(void) 1417{ 1418 int n; 1419 int arg; 1420 TRACE(("params %d (%d)\n", nparam, parms.has_subparams)); 1421 for (arg = 1, n = 0; n < nparam; ++n) { 1422 TRACE(("%3d.%d %d\n", arg, parms.is_sub[n], parms.params[n])); 1423 if (!parms.is_sub[n]) 1424 ++arg; 1425 } 1426} 1427#define DumpParams() dump_params() 1428#else 1429#define DumpParams() /* nothing */ 1430#endif 1431 1432 /* allocate larger buffer if needed/possible */ 1433#define SafeAlloc(type, area, used, size) \ 1434 type *new_string = area; \ 1435 size_t new_length = size; \ 1436 if (new_length == 0) { \ 1437 new_length = 256; \ 1438 new_string = TypeMallocN(type, new_length); \ 1439 } else if (used+1 >= new_length) { \ 1440 new_length = size * 2; \ 1441 new_string = TypeMallocN(type, new_length); \ 1442 if (new_string != 0 \ 1443 && area != 0 \ 1444 && used != 0) { \ 1445 memcpy(new_string, area, used * sizeof(type)); \ 1446 } \ 1447 } 1448#define SafeFree(area, size) \ 1449 if (area != new_string) { \ 1450 free(area); \ 1451 area = new_string; \ 1452 } \ 1453 size = new_length 1454 1455#define WriteNow() { \ 1456 unsigned single = 0; \ 1457 \ 1458 if (screen->curss) { \ 1459 dotext(xw, \ 1460 screen->gsets[(int) (screen->curss)], \ 1461 sp->print_area, \ 1462 (Cardinal) 1); \ 1463 screen->curss = 0; \ 1464 single++; \ 1465 } \ 1466 if (sp->print_used > single) { \ 1467 dotext(xw, \ 1468 screen->gsets[(int) (screen->curgl)], \ 1469 sp->print_area + single, \ 1470 (Cardinal) (sp->print_used - single)); \ 1471 } \ 1472 sp->print_used = 0; \ 1473 } \ 1474 1475struct ParseState { 1476#if OPT_VT52_MODE 1477 Bool vt52_cup; 1478#endif 1479 Const PARSE_T *groundtable; 1480 Const PARSE_T *parsestate; 1481 int scstype; 1482 int scssize; 1483 Bool private_function; /* distinguish private-mode from standard */ 1484 int string_mode; /* nonzero iff we're processing a string */ 1485 int lastchar; /* positive iff we had a graphic character */ 1486 int nextstate; 1487#if OPT_WIDE_CHARS 1488 int last_was_wide; 1489#endif 1490 /* Buffer for processing printable text */ 1491 IChar *print_area; 1492 size_t print_size; 1493 size_t print_used; 1494 /* Buffer for processing strings (e.g., OSC ... ST) */ 1495 Char *string_area; 1496 size_t string_size; 1497 size_t string_used; 1498}; 1499 1500static struct ParseState myState; 1501 1502static void 1503init_groundtable(TScreen *screen, struct ParseState *sp) 1504{ 1505 (void) screen; 1506 1507#if OPT_VT52_MODE 1508 if (!(screen->vtXX_level)) { 1509 sp->groundtable = vt52_table; 1510 } else if (screen->terminal_id >= 100) 1511#endif 1512 { 1513 sp->groundtable = ansi_table; 1514 } 1515} 1516 1517static void 1518select_charset(struct ParseState *sp, int type, int size) 1519{ 1520 TRACE(("select_charset %d %d\n", type, size)); 1521 sp->scstype = type; 1522 sp->scssize = size; 1523 if (size == 94) { 1524 sp->parsestate = scstable; 1525 } else { 1526 sp->parsestate = scs96table; 1527 } 1528} 1529 1530static void 1531decode_scs(XtermWidget xw, int which, int prefix, int suffix) 1532{ 1533 /* *INDENT-OFF* */ 1534 static struct { 1535 DECNRCM_codes result; 1536 int prefix; 1537 int suffix; 1538 int min_level; 1539 int max_level; 1540 int need_nrc; 1541 } table[] = { 1542 { nrc_ASCII, 0, 'B', 1, 9, 0 }, 1543 { nrc_British, 0, 'A', 1, 9, 0 }, 1544 { nrc_DEC_Spec_Graphic, 0, '0', 1, 9, 0 }, 1545 { nrc_DEC_Alt_Chars, 0, '1', 1, 1, 0 }, 1546 { nrc_DEC_Alt_Graphics, 0, '2', 1, 1, 0 }, 1547 /* VT2xx */ 1548 { nrc_DEC_Supp, 0, '<', 2, 9, 0 }, 1549 { nrc_Dutch, 0, '4', 2, 9, 1 }, 1550 { nrc_Finnish, 0, '5', 2, 9, 1 }, 1551 { nrc_Finnish2, 0, 'C', 2, 9, 1 }, 1552 { nrc_French, 0, 'R', 2, 9, 1 }, 1553 { nrc_French2, 0, 'f', 2, 9, 1 }, 1554 { nrc_French_Canadian, 0, 'Q', 2, 9, 1 }, 1555 { nrc_German, 0, 'K', 2, 9, 1 }, 1556 { nrc_Italian, 0, 'Y', 2, 9, 1 }, 1557 { nrc_Norwegian_Danish2, 0, 'E', 2, 9, 1 }, 1558 { nrc_Norwegian_Danish3, 0, '6', 2, 9, 1 }, 1559 { nrc_Spanish, 0, 'Z', 2, 9, 1 }, 1560 { nrc_Swedish, 0, '7', 2, 9, 1 }, 1561 { nrc_Swedish2, 0, 'H', 2, 9, 1 }, 1562 { nrc_Swiss, 0, '=', 2, 9, 1 }, 1563 /* VT3xx */ 1564 { nrc_British_Latin_1, 0, 'A', 3, 9, 1 }, 1565 { nrc_DEC_Supp_Graphic, '%', '5', 3, 9, 0 }, 1566 { nrc_DEC_Technical, 0, '>', 3, 9, 0 }, 1567 { nrc_French_Canadian2, 0, '9', 3, 9, 1 }, 1568 { nrc_Norwegian_Danish, 0, '`', 3, 9, 1 }, 1569 { nrc_Portugese, '%', '6', 3, 9, 1 }, 1570#if 0 1571 /* VT5xx (not implemented) */ 1572 { nrc_Cyrillic, '&', '4', 5, 9, 0 }, 1573 { nrc_Greek, '"', '?', 5, 9, 0 }, 1574 { nrc_Greek_Supp, 0, 'F', 5, 9, 0 }, 1575 { nrc_Hebrew, '"', '4', 5, 9, 0 }, 1576 { nrc_Hebrew2, '%', '=', 5, 9, 1 }, 1577 { nrc_Hebrew_Supp, 0, 'H', 5, 9, 0 }, 1578 { nrc_Latin_5_Supp, 0, 'M', 5, 9, 0 }, 1579 { nrc_Latin_Cyrillic, 0, 'L', 5, 9, 0 }, 1580 { nrc_Russian, '&', '5', 5, 9, 1 }, 1581 { nrc_SCS_NRCS, '%', '3', 5, 9, 0 }, 1582 { nrc_Turkish, '%', '0', 5, 9, 0 }, 1583 { nrc_Turkish2, '%', '2', 5, 9, 1 }, 1584#endif 1585 }; 1586 /* *INDENT-ON* */ 1587 1588 TScreen *screen = TScreenOf(xw); 1589 Cardinal n; 1590 DECNRCM_codes result = nrc_Unknown; 1591 1592 suffix &= 0x7f; 1593 for (n = 0; n < XtNumber(table); ++n) { 1594 if (prefix == table[n].prefix 1595 && suffix == table[n].suffix 1596 && screen->vtXX_level >= table[n].min_level 1597 && screen->vtXX_level <= table[n].max_level 1598 && (table[n].need_nrc == 0 || (xw->flags & NATIONAL) != 0)) { 1599 result = table[n].result; 1600 break; 1601 } 1602 } 1603 if (result != nrc_Unknown) { 1604 screen->gsets[which] = result; 1605 TRACE(("setting G%d to %s\n", which, visibleScsCode((int) result))); 1606 } else { 1607 TRACE(("...unknown GSET\n")); 1608 } 1609} 1610 1611/* 1612 * Given a parameter number, and subparameter (starting in each case from zero) 1613 * return the corresponding index into the parameter array. If the combination 1614 * is not found, return -1. 1615 */ 1616static int 1617subparam_index(int p, int s) 1618{ 1619 int result = -1; 1620 int j, p2, s2; 1621 1622 for (j = p2 = 0; j < nparam; ++j, ++p2) { 1623 if (parms.is_sub[j]) { 1624 s2 = 0; 1625 1626 do { 1627 if ((p == p2) && (s == s2)) { 1628 result = j; 1629 break; 1630 } 1631 ++s2; 1632 } while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])); 1633 1634 if (result >= 0) 1635 break; 1636 1637 --j; /* undo the last "while" */ 1638 } else if (p == p2) { 1639 if (s == 0) { 1640 result = j; 1641 } 1642 break; 1643 } 1644 } 1645 TRACE2(("...subparam_index %d.%d = %d\n", p + 1, s + 1, result)); 1646 return result; 1647} 1648 1649/* 1650 * Check if the given item in the parameter array has subparameters. 1651 * If so, return the number of subparameters to use as a loop limit, etc. 1652 */ 1653static int 1654param_has_subparams(int item) 1655{ 1656 int result = 0; 1657 if (parms.has_subparams) { 1658 int n = subparam_index(item, 0); 1659 if (n >= 0 && parms.is_sub[n]) { 1660 while (n++ < nparam && parms.is_sub[n - 1] < parms.is_sub[n]) { 1661 result++; 1662 } 1663 } 1664 } 1665 TRACE(("...param_has_subparams(%d) ->%d\n", item, result)); 1666 return result; 1667} 1668 1669#if OPT_256_COLORS || OPT_88_COLORS || OPT_ISO_COLORS 1670/* 1671 * Given an index into the parameter array, return the corresponding parameter 1672 * number (starting from zero). 1673 */ 1674static int 1675param_number(int item) 1676{ 1677 int result = -1; 1678 int j, p; 1679 1680 for (j = p = 0; j < nparam; ++j, ++p) { 1681 if (p >= item) { 1682 result = j; 1683 break; 1684 } 1685 if (parms.is_sub[j]) { 1686 while ((++j < nparam) && (parms.is_sub[j - 1] < parms.is_sub[j])) { 1687 /* EMPTY */ 1688 } 1689 --j; 1690 } 1691 } 1692 1693 TRACE2(("...param_number(%d) = %d\n", item, result)); 1694 return result; 1695} 1696 1697static int 1698get_subparam(int p, int s) 1699{ 1700 int item = subparam_index(p, s); 1701 int result = (item >= 0) ? parms.params[item] : DEFAULT; 1702 TRACE(("...get_subparam[%d] = %d\n", item, result)); 1703 return result; 1704} 1705 1706/* 1707 * Some background - 1708 * 1709 * Todd Larason provided the initial changes to support 256-colors in July 1999. 1710 * I pointed out that the description of SGR 38/48 in ECMA-48 was vague, and 1711 * was unsure if there would be some standard using those codes. His response 1712 * was that this was documented (it turns out, in equally vague terms) in ITU 1713 * T.416 1714 * 1715 * Discussing this with Todd Larason in mid-1999, my point was that given the 1716 * high cost of obtaining ITU T.416 (ISO-8613-6), the standard was not going 1717 * to be effective (more than $100 then, more than $200 in 2012) 1718 * 1719 * We overlooked the detail about ":" as a subparameter delimiter (documented 1720 * in 5.4.t2 in ECMA-48). Some discussion in KDE in mid-2006 led Lars Doelle 1721 * to discuss the issue with me. Lars' initial concern dealt with the fact 1722 * that a sequence such as 1723 * CSI 38 ; 5 ; 1 m 1724 * violated the principle that SGR parameters could be used in any order. 1725 * Further discussion (see KDE #107487) resolved that the standard expected 1726 * that the sequence would look like 1727 * CSI 38 ; 5 : 1 m 1728 * which still violates that principle, since the "5:1" parameter has to 1729 * follow the "38" to be useful. 1730 * 1731 * This function accepts either format (per request by Paul Leonerd Evans). 1732 * It also accepts 1733 * CSI 38 : 5 : 1 m 1734 * according to Lars' original assumption. 1735 * 1736 * By the way - all of the parameters are decimal integers. 1737 */ 1738#define extended_colors_limit(n) ((n) == 5 ? 1 : ((n) == 2 ? 3 : 0)) 1739static Boolean 1740parse_extended_colors(XtermWidget xw, int *colorp, int *itemp) 1741{ 1742 Boolean result = False; 1743 int item = *itemp; 1744 int next = item; 1745 int base = param_number(item); 1746 int code = -1; 1747 int values[3]; /* maximum number of subparameters */ 1748 int need = 0; /* number of subparameters needed */ 1749 int have; 1750 int n; 1751 1752 /* 1753 * On entry, 'item' points to the 38/48 code in the parameter array. 1754 * If that has subparameters, we will expect all of the values to 1755 * be subparameters of that item. 1756 */ 1757 if ((have = param_has_subparams(item)) != 0) { 1758 /* accept CSI 38 : 5 : 1 m */ 1759 /* accept CSI 38 : 2 : 1 : 2 : 3 m */ 1760 code = get_subparam(base, 1); 1761 need = extended_colors_limit(code); 1762 next = item + have; 1763 for (n = 0; n < need && n < 3; ++n) { 1764 values[n] = get_subparam(base, 2 + n); 1765 } 1766 } else if (++item < nparam) { 1767 ++base; 1768 if ((have = param_has_subparams(item)) != 0) { 1769 /* accept CSI 38 ; 5 : 1 m */ 1770 /* accept CSI 38 ; 2 : 1 : 2 : 3 m */ 1771 code = get_subparam(base, 0); 1772 need = extended_colors_limit(code); 1773 next = base + have; 1774 for (n = 0; n < need && n < 3; ++n) { 1775 values[n] = get_subparam(base, 1 + n); 1776 } 1777 } else { 1778 /* accept CSI 38 ; 5 ; 1 m */ 1779 /* accept CSI 38 ; 2 ; 1 ; 2 ; 3 m */ 1780 code = GetParam(item); 1781 need = extended_colors_limit(code); 1782 next = item + need; 1783 for (n = 0; n < need && n < 3; ++n) { 1784 values[n] = GetParam(item + 1 + n); 1785 } 1786 } 1787 } 1788 item = next; 1789 1790 switch (code) { 1791 case 2: 1792 /* direct color in rgb space */ 1793 if ((values[0] >= 0 && values[0] < 256) && 1794 (values[1] >= 0 && values[1] < 256) && 1795 (values[2] >= 0 && values[2] < 256)) { 1796 *colorp = xtermClosestColor(xw, values[0], values[1], values[2]); 1797 } else { 1798 *colorp = -1; 1799 } 1800 break; 1801 case 5: 1802 /* indexed color */ 1803 *colorp = values[0]; 1804 break; 1805 default: 1806 *colorp = -1; 1807 break; 1808 } 1809 1810 result = (*colorp >= 0 && *colorp < NUM_ANSI_COLORS); 1811 TRACE(("...resulting color %d/%d %s\n", 1812 *colorp, NUM_ANSI_COLORS, 1813 result ? "OK" : "ERR")); 1814 1815 *itemp = item; 1816 return result; 1817} 1818#endif /* ...extended_colors */ 1819 1820static int 1821optional_param(int which) 1822{ 1823 return (nparam > which) ? GetParam(which) : DEFAULT; 1824} 1825 1826static int 1827zero_if_default(int which) 1828{ 1829 int result = (nparam > which) ? GetParam(which) : 0; 1830 if (result <= 0) 1831 result = 0; 1832 return result; 1833} 1834 1835static int 1836one_if_default(int which) 1837{ 1838 int result = (nparam > which) ? GetParam(which) : 0; 1839 if (result <= 0) 1840 result = 1; 1841 return result; 1842} 1843 1844/* 1845 * Color palette changes using the OSC controls require a repaint of the 1846 * screen - but not immediately. Do the repaint as soon as we detect a 1847 * state which will not lead to another color palette change. 1848 */ 1849static void 1850repaintWhenPaletteChanged(XtermWidget xw, struct ParseState *sp) 1851{ 1852 Boolean ignore = False; 1853 1854 switch (sp->nextstate) { 1855 case CASE_ESC: 1856 ignore = ((sp->parsestate == ansi_table) || 1857 (sp->parsestate == sos_table)); 1858 break; 1859 case CASE_OSC: 1860 ignore = ((sp->parsestate == ansi_table) || 1861 (sp->parsestate == esc_table)); 1862 break; 1863 case CASE_IGNORE: 1864 ignore = (sp->parsestate == sos_table); 1865 break; 1866 case CASE_ST: 1867 ignore = ((sp->parsestate == esc_table) || 1868 (sp->parsestate == sos_table)); 1869 break; 1870 case CASE_ESC_DIGIT: 1871 ignore = (sp->parsestate == csi_table); 1872 break; 1873 case CASE_ESC_SEMI: 1874 ignore = (sp->parsestate == csi2_table); 1875 break; 1876 } 1877 1878 if (!ignore) { 1879 TRACE(("repaintWhenPaletteChanged\n")); 1880 xw->work.palette_changed = False; 1881 xtermRepaint(xw); 1882 } 1883} 1884 1885#if OPT_C1_PRINT || OPT_WIDE_CHARS 1886#define ParseSOS(screen) ((screen)->c1_printable == 0) 1887#else 1888#define ParseSOS(screen) 0 1889#endif 1890 1891#define ResetState(sp) ParamsDone(), (sp)->parsestate = (sp)->groundtable 1892 1893static void 1894illegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp) 1895{ 1896 ResetState(sp); 1897 sp->nextstate = sp->parsestate[E2A(c)]; 1898 Bell(xw, XkbBI_MinorError, 0); 1899} 1900 1901static void 1902init_parser(XtermWidget xw, struct ParseState *sp) 1903{ 1904 TScreen *screen = TScreenOf(xw); 1905 1906 memset(sp, 0, sizeof(*sp)); 1907 sp->scssize = 94; /* number of printable/nonspace ASCII */ 1908 sp->lastchar = -1; /* not a legal IChar */ 1909 sp->nextstate = -1; /* not a legal state */ 1910 1911 init_groundtable(screen, sp); 1912 ResetState(sp); 1913} 1914 1915static void 1916init_reply(unsigned type) 1917{ 1918 memset(&reply, 0, sizeof(reply)); 1919 reply.a_type = (Char) type; 1920} 1921 1922static Boolean 1923doparsing(XtermWidget xw, unsigned c, struct ParseState *sp) 1924{ 1925 TScreen *screen = TScreenOf(xw); 1926 int item; 1927 int count; 1928 int value; 1929 int laststate; 1930 int thischar = -1; 1931 XTermRect myRect; 1932 1933 do { 1934#if OPT_WIDE_CHARS 1935 int this_is_wide = 0; 1936 1937 /* 1938 * Handle zero-width combining characters. Make it faster by noting 1939 * that according to the Unicode charts, the majority of Western 1940 * character sets do not use this feature. There are some unassigned 1941 * codes at 0x242, but no zero-width characters until past 0x300. 1942 */ 1943 if (c >= 0x300 1944 && screen->wide_chars 1945 && my_wcwidth((wchar_t) c) == 0 1946 && !isWideControl(c)) { 1947 int prev, test; 1948 Boolean used = True; 1949 int use_row; 1950 int use_col; 1951 1952 WriteNow(); 1953 use_row = (screen->char_was_written 1954 ? screen->last_written_row 1955 : screen->cur_row); 1956 use_col = (screen->char_was_written 1957 ? screen->last_written_col 1958 : screen->cur_col); 1959 1960 /* 1961 * Check if the latest data can be added to the base character. 1962 * If there is already a combining character stored for the cell, 1963 * we cannot, since that would change the order. 1964 */ 1965 if (screen->normalized_c 1966 && !IsCellCombined(screen, use_row, use_col)) { 1967 prev = (int) XTERM_CELL(use_row, use_col); 1968 test = do_precomposition(prev, (int) c); 1969 TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n", 1970 prev, my_wcwidth((wchar_t) prev), 1971 (int) c, my_wcwidth((wchar_t) c), 1972 test, my_wcwidth((wchar_t) test))); 1973 } else { 1974 prev = -1; 1975 test = -1; 1976 } 1977 1978 /* substitute combined character with precomposed character 1979 * only if it does not change the width of the base character 1980 */ 1981 if (test != -1 1982 && my_wcwidth((wchar_t) test) == my_wcwidth((wchar_t) prev)) { 1983 putXtermCell(screen, use_row, use_col, test); 1984 } else if (screen->char_was_written 1985 || getXtermCell(screen, use_row, use_col) > ' ') { 1986 addXtermCombining(screen, use_row, use_col, c); 1987 } else { 1988 /* 1989 * none of the above... we will add the combining character as 1990 * a base character. 1991 */ 1992 used = False; 1993 } 1994 1995 if (used) { 1996 if (!screen->scroll_amt) 1997 ScrnUpdate(xw, use_row, use_col, 1, 1, 1); 1998 continue; 1999 } 2000 } 2001#endif 2002 2003 /* Intercept characters for printer controller mode */ 2004 if (PrinterOf(screen).printer_controlmode == 2) { 2005 if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0) 2006 continue; 2007 } 2008 2009 /* 2010 * VT52 is a little ugly in the one place it has a parameterized 2011 * control sequence, since the parameter falls after the character 2012 * that denotes the type of sequence. 2013 */ 2014#if OPT_VT52_MODE 2015 if (sp->vt52_cup) { 2016 if (nparam < NPARAM - 1) { 2017 SetParam(nparam++, (int) (c & 0x7f) - 32); 2018 parms.is_sub[nparam] = 0; 2019 } 2020 if (nparam < 2) 2021 continue; 2022 sp->vt52_cup = False; 2023 CursorSet(screen, zero_if_default(0), zero_if_default(1), xw->flags); 2024 sp->parsestate = vt52_table; 2025 SetParam(0, 0); 2026 SetParam(1, 0); 2027 continue; 2028 } 2029#endif 2030 2031 laststate = sp->nextstate; 2032 if (c == ANSI_DEL 2033 && sp->parsestate == sp->groundtable 2034 && sp->scssize == 96 2035 && sp->scstype != 0) { 2036 /* 2037 * Handle special case of shifts for 96-character sets by checking 2038 * if we have a DEL. The other special case for SPACE will always 2039 * be printable. 2040 */ 2041 sp->nextstate = CASE_PRINT; 2042 } else 2043#if OPT_WIDE_CHARS 2044 if (c > 255) { 2045 /* 2046 * The parsing tables all have 256 entries. If we're supporting 2047 * wide characters, we handle them by treating them the same as 2048 * printing characters. 2049 */ 2050 if (sp->parsestate == sp->groundtable) { 2051 sp->nextstate = CASE_PRINT; 2052 } else if (sp->parsestate == sos_table) { 2053 c &= 0xffff; 2054 if (c > 255) { 2055 TRACE(("Found code > 255 while in SOS state: %04X\n", c)); 2056 c = '?'; 2057 } 2058 } else { 2059 sp->nextstate = CASE_GROUND_STATE; 2060 } 2061 } else 2062#endif 2063 sp->nextstate = sp->parsestate[E2A(c)]; 2064 2065#if OPT_BROKEN_OSC 2066 /* 2067 * Linux console palette escape sequences start with an OSC, but do 2068 * not terminate correctly. Some scripts do not check before writing 2069 * them, making xterm appear to hang (it's awaiting a valid string 2070 * terminator). Just ignore these if we see them - there's no point 2071 * in emulating bad code. 2072 */ 2073 if (screen->brokenLinuxOSC 2074 && sp->parsestate == sos_table) { 2075 if (sp->string_used) { 2076 switch (sp->string_area[0]) { 2077 case 'P': 2078 if (sp->string_used <= 7) 2079 break; 2080 /* FALLTHRU */ 2081 case 'R': 2082 illegal_parse(xw, c, sp); 2083 TRACE(("Reset to ground state (brokenLinuxOSC)\n")); 2084 break; 2085 } 2086 } 2087 } 2088#endif 2089 2090#if OPT_BROKEN_ST 2091 /* 2092 * Before patch #171, carriage control embedded within an OSC string 2093 * would terminate it. Some (buggy, of course) applications rely on 2094 * this behavior. Accommodate them by allowing one to compile xterm 2095 * and emulate the old behavior. 2096 */ 2097 if (screen->brokenStringTerm 2098 && sp->parsestate == sos_table 2099 && c < 32) { 2100 switch (c) { 2101 case ANSI_EOT: /* FALLTHRU */ 2102 case ANSI_BS: /* FALLTHRU */ 2103 case ANSI_HT: /* FALLTHRU */ 2104 case ANSI_LF: /* FALLTHRU */ 2105 case ANSI_VT: /* FALLTHRU */ 2106 case ANSI_FF: /* FALLTHRU */ 2107 case ANSI_CR: /* FALLTHRU */ 2108 case ANSI_SO: /* FALLTHRU */ 2109 case ANSI_SI: /* FALLTHRU */ 2110 case ANSI_XON: /* FALLTHRU */ 2111 case ANSI_CAN: 2112 illegal_parse(xw, c, sp); 2113 TRACE(("Reset to ground state (brokenStringTerm)\n")); 2114 break; 2115 } 2116 } 2117#endif 2118 2119#if OPT_C1_PRINT 2120 /* 2121 * This is not completely foolproof, but will allow an application 2122 * with values in the C1 range to use them as printable characters, 2123 * provided that they are not intermixed with an escape sequence. 2124 */ 2125 if (screen->c1_printable 2126 && (c >= 128 && c < 256)) { 2127 sp->nextstate = (sp->parsestate == esc_table 2128 ? CASE_ESC_IGNORE 2129 : sp->parsestate[E2A(160)]); 2130 TRACE(("allowC1Printable %04X %s ->%s\n", 2131 c, which_table(sp->parsestate), 2132 visibleVTparse(sp->nextstate))); 2133 } 2134#endif 2135 2136#if OPT_WIDE_CHARS 2137 /* 2138 * If we have a C1 code and the c1_printable flag is not set, simply 2139 * ignore it when it was translated from UTF-8. That is because the 2140 * value could not have been present as-is in the UTF-8. 2141 * 2142 * To see that CASE_IGNORE is a consistent value, note that it is 2143 * always used for NUL and other uninteresting C0 controls. 2144 */ 2145#if OPT_C1_PRINT 2146 if (!screen->c1_printable) 2147#endif 2148 if (screen->wide_chars 2149 && (c >= 128 && c < 160)) { 2150 sp->nextstate = CASE_IGNORE; 2151 } 2152 2153 /* 2154 * If this character is a different width than the last one, put the 2155 * previous text into the buffer and draw it now. 2156 */ 2157 this_is_wide = isWide((int) c); 2158 if (this_is_wide != sp->last_was_wide) { 2159 WriteNow(); 2160 } 2161#endif 2162 2163 /* 2164 * Accumulate string for printable text. This may be 8/16-bit 2165 * characters. 2166 */ 2167 if (sp->nextstate == CASE_PRINT) { 2168 SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size); 2169 if (new_string == 0) { 2170 xtermWarning("Cannot allocate %lu bytes for printable text\n", 2171 (unsigned long) new_length); 2172 continue; 2173 } 2174 SafeFree(sp->print_area, sp->print_size); 2175#if OPT_VT52_MODE 2176 /* 2177 * Strip output text to 7-bits for VT52. We should do this for 2178 * VT100 also (which is a 7-bit device), but xterm has been 2179 * doing this for so long we shouldn't change this behavior. 2180 */ 2181 if (screen->vtXX_level < 1) 2182 c &= 0x7f; 2183#endif 2184 sp->print_area[sp->print_used++] = (IChar) c; 2185 sp->lastchar = thischar = (int) c; 2186#if OPT_WIDE_CHARS 2187 sp->last_was_wide = this_is_wide; 2188#endif 2189 if (morePtyData(screen, VTbuffer)) { 2190 continue; 2191 } 2192 } 2193 2194 if (sp->nextstate == CASE_PRINT 2195 || (laststate == CASE_PRINT && sp->print_used)) { 2196 WriteNow(); 2197 } 2198 2199 /* 2200 * Accumulate string for APC, DCS, PM, OSC, SOS controls 2201 * This should always be 8-bit characters. 2202 */ 2203 if (sp->parsestate == sos_table) { 2204 SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size); 2205 if (new_string == 0) { 2206 xtermWarning("Cannot allocate %lu bytes for string mode %d\n", 2207 (unsigned long) new_length, sp->string_mode); 2208 continue; 2209 } 2210 SafeFree(sp->string_area, sp->string_size); 2211#if OPT_WIDE_CHARS 2212 /* 2213 * We cannot display codes above 255, but let's try to 2214 * accommodate the application a little by not aborting the 2215 * string. 2216 */ 2217 if ((c & 0xffff) > 255) { 2218 sp->nextstate = CASE_PRINT; 2219 c = '?'; 2220 } 2221#endif 2222 sp->string_area[(sp->string_used)++] = CharOf(c); 2223 } else if (sp->parsestate != esc_table) { 2224 /* if we were accumulating, we're not any more */ 2225 sp->string_mode = 0; 2226 sp->string_used = 0; 2227 } 2228 2229 DumpParams(); 2230 TRACE(("parse %04X -> %s %s (used=%lu)\n", 2231 c, visibleVTparse(sp->nextstate), 2232 which_table(sp->parsestate), 2233 (unsigned long) sp->string_used)); 2234 2235 /* 2236 * If the parameter list has subparameters (tokens separated by ":") 2237 * reject any controls that do not accept subparameters. 2238 */ 2239 if (parms.has_subparams) { 2240 switch (sp->nextstate) { 2241 case CASE_GROUND_STATE: 2242 case CASE_CSI_IGNORE: 2243 /* FALLTHRU */ 2244 2245 case CASE_ESC_DIGIT: 2246 case CASE_ESC_SEMI: 2247 case CASE_ESC_COLON: 2248 /* these states are required to parse parameter lists */ 2249 break; 2250 2251 case CASE_SGR: 2252 TRACE(("...possible subparam usage\n")); 2253 break; 2254 2255 case CASE_CSI_DEC_DOLLAR_STATE: 2256 case CASE_CSI_DOLLAR_STATE: 2257 case CASE_CSI_EX_STATE: 2258 case CASE_CSI_QUOTE_STATE: 2259 case CASE_CSI_SPACE_STATE: 2260 case CASE_CSI_STAR_STATE: 2261 case CASE_CSI_TICK_STATE: 2262 case CASE_DEC2_STATE: 2263 case CASE_DEC3_STATE: 2264 case CASE_DEC_STATE: 2265 /* use this branch when we do not yet have the final character */ 2266 TRACE(("...unexpected subparam usage\n")); 2267 ParamsDone(); 2268 sp->nextstate = CASE_CSI_IGNORE; 2269 break; 2270 2271 default: 2272 /* use this branch for cases where we have the final character 2273 * in the table that processed the parameter list. 2274 */ 2275 TRACE(("...unexpected subparam usage\n")); 2276 ResetState(sp); 2277 continue; 2278 } 2279 } 2280 2281 if (xw->work.palette_changed) { 2282 repaintWhenPaletteChanged(xw, sp); 2283 } 2284 2285 switch (sp->nextstate) { 2286 case CASE_PRINT: 2287 TRACE(("CASE_PRINT - printable characters\n")); 2288 break; 2289 2290 case CASE_GROUND_STATE: 2291 TRACE(("CASE_GROUND_STATE - exit ignore mode\n")); 2292 ResetState(sp); 2293 break; 2294 2295 case CASE_IGNORE: 2296 TRACE(("CASE_IGNORE - Ignore character %02X\n", c)); 2297 break; 2298 2299 case CASE_ENQ: 2300 TRACE(("CASE_ENQ - answerback\n")); 2301 for (count = 0; screen->answer_back[count] != 0; count++) 2302 unparseputc(xw, screen->answer_back[count]); 2303 unparse_end(xw); 2304 break; 2305 2306 case CASE_BELL: 2307 TRACE(("CASE_BELL - bell\n")); 2308 if (sp->string_mode == ANSI_OSC) { 2309 if (sp->string_used) 2310 sp->string_area[--(sp->string_used)] = '\0'; 2311 do_osc(xw, sp->string_area, sp->string_used, (int) c); 2312 ResetState(sp); 2313 } else { 2314 /* bell */ 2315 Bell(xw, XkbBI_TerminalBell, 0); 2316 } 2317 break; 2318 2319 case CASE_BS: 2320 TRACE(("CASE_BS - backspace\n")); 2321 CursorBack(xw, 1); 2322 break; 2323 2324 case CASE_CR: 2325 TRACE(("CASE_CR\n")); 2326 CarriageReturn(xw); 2327 break; 2328 2329 case CASE_ESC: 2330 if_OPT_VT52_MODE(screen, { 2331 sp->parsestate = vt52_esc_table; 2332 break; 2333 }); 2334 sp->parsestate = esc_table; 2335 break; 2336 2337#if OPT_VT52_MODE 2338 case CASE_VT52_CUP: 2339 TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n")); 2340 sp->vt52_cup = True; 2341 InitParams(); 2342 break; 2343 2344 case CASE_VT52_IGNORE: 2345 TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n")); 2346 sp->parsestate = vt52_ignore_table; 2347 break; 2348#endif 2349 2350 case CASE_VMOT: 2351 TRACE(("CASE_VMOT\n")); 2352 /* 2353 * form feed, line feed, vertical tab 2354 */ 2355 xtermAutoPrint(xw, c); 2356 xtermIndex(xw, 1); 2357 if (xw->flags & LINEFEED) 2358 CarriageReturn(xw); 2359 else 2360 do_xevents(); 2361 break; 2362 2363 case CASE_CBT: 2364 TRACE(("CASE_CBT\n")); 2365 /* cursor backward tabulation */ 2366 count = one_if_default(0); 2367 while ((count-- > 0) 2368 && (TabToPrevStop(xw))) ; 2369 ResetState(sp); 2370 break; 2371 2372 case CASE_CHT: 2373 TRACE(("CASE_CHT\n")); 2374 /* cursor forward tabulation */ 2375 count = one_if_default(0); 2376 while ((count-- > 0) 2377 && (TabToNextStop(xw))) ; 2378 ResetState(sp); 2379 break; 2380 2381 case CASE_TAB: 2382 /* tab */ 2383 TabToNextStop(xw); 2384 break; 2385 2386 case CASE_SI: 2387 screen->curgl = 0; 2388 if_OPT_VT52_MODE(screen, { 2389 ResetState(sp); 2390 }); 2391 break; 2392 2393 case CASE_SO: 2394 screen->curgl = 1; 2395 if_OPT_VT52_MODE(screen, { 2396 ResetState(sp); 2397 }); 2398 break; 2399 2400 case CASE_DECDHL: 2401 xterm_DECDHL(xw, c == '3'); 2402 ResetState(sp); 2403 break; 2404 2405 case CASE_DECSWL: 2406 xterm_DECSWL(xw); 2407 ResetState(sp); 2408 break; 2409 2410 case CASE_DECDWL: 2411 xterm_DECDWL(xw); 2412 ResetState(sp); 2413 break; 2414 2415 case CASE_SCR_STATE: 2416 /* enter scr state */ 2417 sp->parsestate = scrtable; 2418 break; 2419 2420 case CASE_SCS0_STATE: 2421 /* enter scs state 0 */ 2422 select_charset(sp, 0, 94); 2423 break; 2424 2425 case CASE_SCS1_STATE: 2426 /* enter scs state 1 */ 2427 select_charset(sp, 1, 94); 2428 break; 2429 2430 case CASE_SCS2_STATE: 2431 /* enter scs state 2 */ 2432 select_charset(sp, 2, 94); 2433 break; 2434 2435 case CASE_SCS3_STATE: 2436 /* enter scs state 3 */ 2437 select_charset(sp, 3, 94); 2438 break; 2439 2440 case CASE_SCS1A_STATE: 2441 /* enter scs state 1 */ 2442 select_charset(sp, 1, 96); 2443 break; 2444 2445 case CASE_SCS2A_STATE: 2446 /* enter scs state 2 */ 2447 select_charset(sp, 2, 96); 2448 break; 2449 2450 case CASE_SCS3A_STATE: 2451 /* enter scs state 3 */ 2452 select_charset(sp, 3, 96); 2453 break; 2454 2455 case CASE_ESC_IGNORE: 2456 /* unknown escape sequence */ 2457 sp->parsestate = eigtable; 2458 break; 2459 2460 case CASE_ESC_DIGIT: 2461 /* digit in csi or dec mode */ 2462 if (nparam > 0) { 2463 value = zero_if_default(nparam - 1); 2464 SetParam(nparam - 1, (10 * value) + ((int) c - '0')); 2465 if (GetParam(nparam - 1) > 65535) 2466 SetParam(nparam - 1, 65535); 2467 if (sp->parsestate == csi_table) 2468 sp->parsestate = csi2_table; 2469 } 2470 break; 2471 2472 case CASE_ESC_SEMI: 2473 /* semicolon in csi or dec mode */ 2474 if (nparam < NPARAM) { 2475 parms.is_sub[nparam] = 0; 2476 SetParam(nparam++, DEFAULT); 2477 } 2478 if (sp->parsestate == csi_table) 2479 sp->parsestate = csi2_table; 2480 break; 2481 2482 /* 2483 * A _few_ commands accept colon-separated subparameters. 2484 * Mark the parameter list so that we can exclude (most) bogus 2485 * commands with simple/fast checks. 2486 */ 2487 case CASE_ESC_COLON: 2488 if (nparam < NPARAM) { 2489 parms.has_subparams = 1; 2490 if (nparam == 0) { 2491 parms.is_sub[nparam] = 1; 2492 SetParam(nparam++, DEFAULT); 2493 } else if (parms.is_sub[nparam - 1] == 0) { 2494 parms.is_sub[nparam - 1] = 1; 2495 parms.is_sub[nparam] = 2; 2496 parms.params[nparam] = 0; 2497 ++nparam; 2498 } else { 2499 parms.is_sub[nparam] = 1 + parms.is_sub[nparam - 1]; 2500 parms.params[nparam] = 0; 2501 ++nparam; 2502 } 2503 } 2504 break; 2505 2506 case CASE_DEC_STATE: 2507 /* enter dec mode */ 2508 sp->parsestate = dec_table; 2509 break; 2510 2511 case CASE_DEC2_STATE: 2512 /* enter dec2 mode */ 2513 sp->parsestate = dec2_table; 2514 break; 2515 2516 case CASE_DEC3_STATE: 2517 /* enter dec3 mode */ 2518 sp->parsestate = dec3_table; 2519 break; 2520 2521 case CASE_ICH: 2522 TRACE(("CASE_ICH - insert char\n")); 2523 InsertChar(xw, (unsigned) one_if_default(0)); 2524 ResetState(sp); 2525 break; 2526 2527 case CASE_CUU: 2528 TRACE(("CASE_CUU - cursor up\n")); 2529 CursorUp(screen, one_if_default(0)); 2530 ResetState(sp); 2531 break; 2532 2533 case CASE_CUD: 2534 TRACE(("CASE_CUD - cursor down\n")); 2535 CursorDown(screen, one_if_default(0)); 2536 ResetState(sp); 2537 break; 2538 2539 case CASE_CUF: 2540 TRACE(("CASE_CUF - cursor forward\n")); 2541 CursorForward(xw, one_if_default(0)); 2542 ResetState(sp); 2543 break; 2544 2545 case CASE_CUB: 2546 TRACE(("CASE_CUB - cursor backward\n")); 2547 CursorBack(xw, one_if_default(0)); 2548 ResetState(sp); 2549 break; 2550 2551 case CASE_CUP: 2552 TRACE(("CASE_CUP - cursor position\n")); 2553 if_OPT_XMC_GLITCH(screen, { 2554 Jump_XMC(xw); 2555 }); 2556 CursorSet(screen, one_if_default(0) - 1, one_if_default(1) - 1, xw->flags); 2557 ResetState(sp); 2558 break; 2559 2560 case CASE_VPA: 2561 TRACE(("CASE_VPA - vertical position absolute\n")); 2562 CursorSet(screen, one_if_default(0) - 1, CursorCol(xw), xw->flags); 2563 ResetState(sp); 2564 break; 2565 2566 case CASE_HPA: 2567 TRACE(("CASE_HPA - horizontal position absolute\n")); 2568 CursorSet(screen, CursorRow(xw), one_if_default(0) - 1, xw->flags); 2569 ResetState(sp); 2570 break; 2571 2572 case CASE_VPR: 2573 TRACE(("CASE_VPR - vertical position relative\n")); 2574 CursorSet(screen, 2575 CursorRow(xw) + one_if_default(0), 2576 CursorCol(xw), 2577 xw->flags); 2578 ResetState(sp); 2579 break; 2580 2581 case CASE_HPR: 2582 TRACE(("CASE_HPR - horizontal position relative\n")); 2583 CursorSet(screen, 2584 CursorRow(xw), 2585 CursorCol(xw) + one_if_default(0), 2586 xw->flags); 2587 ResetState(sp); 2588 break; 2589 2590 case CASE_HP_BUGGY_LL: 2591 TRACE(("CASE_HP_BUGGY_LL\n")); 2592 /* Some HP-UX applications have the bug that they 2593 assume ESC F goes to the lower left corner of 2594 the screen, regardless of what terminfo says. */ 2595 if (screen->hp_ll_bc) 2596 CursorSet(screen, screen->max_row, 0, xw->flags); 2597 ResetState(sp); 2598 break; 2599 2600 case CASE_ED: 2601 TRACE(("CASE_ED - erase display\n")); 2602 do_cd_xtra_scroll(xw); 2603 do_erase_display(xw, zero_if_default(0), OFF_PROTECT); 2604 ResetState(sp); 2605 break; 2606 2607 case CASE_EL: 2608 TRACE(("CASE_EL - erase line\n")); 2609 do_erase_line(xw, zero_if_default(0), OFF_PROTECT); 2610 ResetState(sp); 2611 break; 2612 2613 case CASE_ECH: 2614 TRACE(("CASE_ECH - erase char\n")); 2615 /* ECH */ 2616 ClearRight(xw, one_if_default(0)); 2617 ResetState(sp); 2618 break; 2619 2620 case CASE_IL: 2621 TRACE(("CASE_IL - insert line\n")); 2622 set_cur_col(screen, ScrnLeftMargin(xw)); 2623 InsertLine(xw, one_if_default(0)); 2624 ResetState(sp); 2625 break; 2626 2627 case CASE_DL: 2628 TRACE(("CASE_DL - delete line\n")); 2629 set_cur_col(screen, ScrnLeftMargin(xw)); 2630 DeleteLine(xw, one_if_default(0)); 2631 ResetState(sp); 2632 break; 2633 2634 case CASE_DCH: 2635 TRACE(("CASE_DCH - delete char\n")); 2636 DeleteChar(xw, (unsigned) one_if_default(0)); 2637 ResetState(sp); 2638 break; 2639 2640 case CASE_TRACK_MOUSE: 2641 /* 2642 * A single parameter other than zero is always scroll-down. 2643 * A zero-parameter is used to reset the mouse mode, and is 2644 * not useful for scrolling anyway. 2645 */ 2646 if (nparam > 1 || GetParam(0) == 0) { 2647 CELL start; 2648 2649 TRACE(("CASE_TRACK_MOUSE\n")); 2650 /* Track mouse as long as in window and between 2651 * specified rows 2652 */ 2653 start.row = one_if_default(2) - 1; 2654 start.col = GetParam(1) - 1; 2655 TrackMouse(xw, 2656 GetParam(0), 2657 &start, 2658 GetParam(3) - 1, GetParam(4) - 2); 2659 } else { 2660 TRACE(("CASE_SD - scroll down\n")); 2661 /* SD */ 2662 RevScroll(xw, one_if_default(0)); 2663 do_xevents(); 2664 } 2665 ResetState(sp); 2666 break; 2667 2668 case CASE_DECID: 2669 TRACE(("CASE_DECID\n")); 2670 if_OPT_VT52_MODE(screen, { 2671 unparseputc(xw, ANSI_ESC); 2672 unparseputc(xw, '/'); 2673 unparseputc(xw, 'Z'); 2674 unparse_end(xw); 2675 ResetState(sp); 2676 break; 2677 }); 2678 SetParam(0, DEFAULT); /* Default ID parameter */ 2679 /* FALLTHRU */ 2680 case CASE_DA1: 2681 TRACE(("CASE_DA1\n")); 2682 if (GetParam(0) <= 0) { /* less than means DEFAULT */ 2683 count = 0; 2684 init_reply(ANSI_CSI); 2685 reply.a_pintro = '?'; 2686 2687 /* 2688 * The first parameter corresponds to the highest operating 2689 * level (i.e., service level) of the emulation. A DEC 2690 * terminal can be setup to respond with a different DA 2691 * response, but there's no control sequence that modifies 2692 * this. We set it via a resource. 2693 */ 2694 if (screen->terminal_id < 200) { 2695 switch (screen->terminal_id) { 2696 case 125: 2697 reply.a_param[count++] = 12; /* VT125 */ 2698#if OPT_REGIS_GRAPHICS 2699 reply.a_param[count++] = 0 | 2 | 1; /* no STP, AVO, GPO (ReGIS) */ 2700#else 2701 reply.a_param[count++] = 0 | 2 | 0; /* no STP, AVO, no GPO (ReGIS) */ 2702#endif 2703 reply.a_param[count++] = 0; /* no printer */ 2704 reply.a_param[count++] = XTERM_PATCH; /* ROM version */ 2705 break; 2706 case 102: 2707 reply.a_param[count++] = 6; /* VT102 */ 2708 break; 2709 case 101: 2710 reply.a_param[count++] = 1; /* VT101 */ 2711 reply.a_param[count++] = 0; /* no options */ 2712 break; 2713 default: /* VT100 */ 2714 reply.a_param[count++] = 1; /* VT100 */ 2715 reply.a_param[count++] = 0 | 2 | 0; /* no STP, AVO, no GPO (ReGIS) */ 2716 break; 2717 } 2718 } else { 2719 reply.a_param[count++] = (ParmType) (60 2720 + screen->terminal_id 2721 / 100); 2722 reply.a_param[count++] = 1; /* 132-columns */ 2723 reply.a_param[count++] = 2; /* printer */ 2724#if OPT_REGIS_GRAPHICS 2725 if (screen->terminal_id == 240 || 2726 screen->terminal_id == 241 || 2727 screen->terminal_id == 330 || 2728 screen->terminal_id == 340) { 2729 reply.a_param[count++] = 3; /* ReGIS graphics */ 2730 } 2731#endif 2732#if OPT_SIXEL_GRAPHICS 2733 if (screen->terminal_id == 240 || 2734 screen->terminal_id == 241 || 2735 screen->terminal_id == 330 || 2736 screen->terminal_id == 340 || 2737 screen->terminal_id == 382) { 2738 reply.a_param[count++] = 4; /* sixel graphics */ 2739 } 2740#endif 2741 reply.a_param[count++] = 6; /* selective-erase */ 2742#if OPT_SUNPC_KBD 2743 if (xw->keyboard.type == keyboardIsVT220) 2744#endif 2745 reply.a_param[count++] = 8; /* user-defined-keys */ 2746 reply.a_param[count++] = 9; /* national replacement charsets */ 2747 reply.a_param[count++] = 15; /* technical characters */ 2748 if (screen->terminal_id >= 400) { 2749 reply.a_param[count++] = 18; /* windowing capability */ 2750 reply.a_param[count++] = 21; /* horizontal scrolling */ 2751 } 2752 if_OPT_ISO_COLORS(screen, { 2753 reply.a_param[count++] = 22; /* ANSI color, VT525 */ 2754 }); 2755#if OPT_DEC_LOCATOR 2756 reply.a_param[count++] = 29; /* ANSI text locator */ 2757#endif 2758 } 2759 reply.a_nparam = (ParmType) count; 2760 reply.a_inters = 0; 2761 reply.a_final = 'c'; 2762 unparseseq(xw, &reply); 2763 } 2764 ResetState(sp); 2765 break; 2766 2767 case CASE_DA2: 2768 TRACE(("CASE_DA2\n")); 2769 if (GetParam(0) <= 0) { /* less than means DEFAULT */ 2770 count = 0; 2771 init_reply(ANSI_CSI); 2772 reply.a_pintro = '>'; 2773 2774 if (screen->terminal_id >= 200) { 2775 switch (screen->terminal_id) { 2776 case 220: 2777 default: 2778 reply.a_param[count++] = 1; /* VT220 */ 2779 break; 2780 case 240: 2781 /* http://www.decuslib.com/DECUS/vax87a/gendyn/vt200_kind.lis */ 2782 reply.a_param[count++] = 2; /* VT240 */ 2783 break; 2784 case 320: 2785 /* http://www.vt100.net/docs/vt320-uu/appendixe.html */ 2786 reply.a_param[count++] = 24; /* VT320 */ 2787 break; 2788 case 330: 2789 reply.a_param[count++] = 18; /* VT330 */ 2790 break; 2791 case 340: 2792 reply.a_param[count++] = 19; /* VT340 */ 2793 break; 2794 case 420: 2795 reply.a_param[count++] = 41; /* VT420 */ 2796 break; 2797 case 510: 2798 /* http://www.vt100.net/docs/vt510-rm/DA2 */ 2799 reply.a_param[count++] = 61; /* VT510 */ 2800 break; 2801 case 520: 2802 reply.a_param[count++] = 64; /* VT520 */ 2803 break; 2804 case 525: 2805 reply.a_param[count++] = 65; /* VT525 */ 2806 break; 2807 } 2808 } else { 2809 reply.a_param[count++] = 0; /* VT100 (nonstandard) */ 2810 } 2811 reply.a_param[count++] = XTERM_PATCH; /* Version */ 2812 reply.a_param[count++] = 0; /* options (none) */ 2813 reply.a_nparam = (ParmType) count; 2814 reply.a_inters = 0; 2815 reply.a_final = 'c'; 2816 unparseseq(xw, &reply); 2817 } 2818 ResetState(sp); 2819 break; 2820 2821 case CASE_DECRPTUI: 2822 TRACE(("CASE_DECRPTUI\n")); 2823 if ((screen->vtXX_level >= 4) 2824 && (GetParam(0) <= 0)) { /* less than means DEFAULT */ 2825 unparseputc1(xw, ANSI_DCS); 2826 unparseputc(xw, '!'); 2827 unparseputc(xw, '|'); 2828 unparseputc(xw, '0'); 2829 unparseputc1(xw, ANSI_ST); 2830 unparse_end(xw); 2831 } 2832 ResetState(sp); 2833 break; 2834 2835 case CASE_TBC: 2836 TRACE(("CASE_TBC - tab clear\n")); 2837 if ((value = GetParam(0)) <= 0) /* less than means default */ 2838 TabClear(xw->tabs, screen->cur_col); 2839 else if (value == 3) 2840 TabZonk(xw->tabs); 2841 ResetState(sp); 2842 break; 2843 2844 case CASE_SET: 2845 TRACE(("CASE_SET - set mode\n")); 2846 ansi_modes(xw, bitset); 2847 ResetState(sp); 2848 break; 2849 2850 case CASE_RST: 2851 TRACE(("CASE_RST - reset mode\n")); 2852 ansi_modes(xw, bitclr); 2853 ResetState(sp); 2854 break; 2855 2856 case CASE_SGR: 2857 for (item = 0; item < nparam; ++item) { 2858 int op = GetParam(item); 2859 2860 if_OPT_XMC_GLITCH(screen, { 2861 Mark_XMC(xw, op); 2862 }); 2863 TRACE(("CASE_SGR %d\n", op)); 2864 2865 /* 2866 * Only SGR 38/48 accept subparameters, and in those cases 2867 * the values will not be seen at this point. 2868 */ 2869 if (param_has_subparams(item)) { 2870 switch (op) { 2871 case 38: 2872 /* FALLTHRU */ 2873 case 48: 2874 if_OPT_ISO_COLORS(screen, { 2875 break; 2876 }); 2877 /* FALLTHRU */ 2878 default: 2879 TRACE(("...unexpected subparameter in SGR\n")); 2880 op = 9999; 2881 ResetState(sp); 2882 break; 2883 } 2884 } 2885 2886 switch (op) { 2887 case DEFAULT: 2888 /* FALLTHRU */ 2889 case 0: 2890#if OPT_WIDE_ATTRS 2891 setItalicFont(xw, False); 2892#endif 2893 UIntClr(xw->flags, 2894 (SGR_MASK | SGR_MASK2 | INVISIBLE)); 2895 if_OPT_ISO_COLORS(screen, { 2896 reset_SGR_Colors(xw); 2897 }); 2898 break; 2899 case 1: /* Bold */ 2900 UIntSet(xw->flags, BOLD); 2901 if_OPT_ISO_COLORS(screen, { 2902 setExtendedFG(xw); 2903 }); 2904 break; 2905#if OPT_WIDE_ATTRS 2906 case 2: /* faint, decreased intensity or second colour */ 2907 UIntSet(xw->flags, ATR_FAINT); 2908 if_OPT_ISO_COLORS(screen, { 2909 setExtendedFG(xw); 2910 }); 2911 break; 2912 case 3: /* italicized */ 2913 setItalicFont(xw, UseItalicFont(screen)); 2914 UIntSet(xw->flags, ATR_ITALIC); 2915 if_OPT_ISO_COLORS(screen, { 2916 setExtendedFG(xw); 2917 }); 2918 break; 2919#endif 2920 case 4: /* Underscore */ 2921 UIntSet(xw->flags, UNDERLINE); 2922 if_OPT_ISO_COLORS(screen, { 2923 setExtendedFG(xw); 2924 }); 2925 break; 2926 case 5: /* Blink */ 2927 UIntSet(xw->flags, BLINK); 2928 StartBlinking(screen); 2929 if_OPT_ISO_COLORS(screen, { 2930 setExtendedFG(xw); 2931 }); 2932 break; 2933 case 7: 2934 UIntSet(xw->flags, INVERSE); 2935 if_OPT_ISO_COLORS(screen, { 2936 setExtendedBG(xw); 2937 }); 2938 break; 2939 case 8: 2940 UIntSet(xw->flags, INVISIBLE); 2941 break; 2942#if OPT_WIDE_ATTRS 2943 case 9: /* crossed-out characters */ 2944 UIntSet(xw->flags, ATR_STRIKEOUT); 2945 break; 2946#endif 2947#if OPT_WIDE_ATTRS 2948 case 21: /* doubly-underlined */ 2949 UIntSet(xw->flags, ATR_DBL_UNDER); 2950 break; 2951#endif 2952 case 22: /* reset 'bold' */ 2953 UIntClr(xw->flags, BOLD); 2954#if OPT_WIDE_ATTRS 2955 UIntClr(xw->flags, ATR_FAINT); 2956#endif 2957 if_OPT_ISO_COLORS(screen, { 2958 setExtendedFG(xw); 2959 }); 2960 break; 2961#if OPT_WIDE_ATTRS 2962 case 23: /* not italicized */ 2963 setItalicFont(xw, False); 2964 UIntClr(xw->flags, ATR_ITALIC); 2965 if_OPT_ISO_COLORS(screen, { 2966 setExtendedFG(xw); 2967 }); 2968 break; 2969#endif 2970 case 24: 2971 UIntClr(xw->flags, UNDERLINE); 2972#if OPT_WIDE_ATTRS 2973 UIntClr(xw->flags, ATR_DBL_UNDER); 2974#endif 2975 if_OPT_ISO_COLORS(screen, { 2976 setExtendedFG(xw); 2977 }); 2978 break; 2979 case 25: /* reset 'blink' */ 2980 UIntClr(xw->flags, BLINK); 2981 if_OPT_ISO_COLORS(screen, { 2982 setExtendedFG(xw); 2983 }); 2984 break; 2985 case 27: 2986 UIntClr(xw->flags, INVERSE); 2987 if_OPT_ISO_COLORS(screen, { 2988 setExtendedBG(xw); 2989 }); 2990 break; 2991 case 28: 2992 UIntClr(xw->flags, INVISIBLE); 2993 break; 2994#if OPT_WIDE_ATTRS 2995 case 29: /* not crossed out */ 2996 UIntClr(xw->flags, ATR_STRIKEOUT); 2997 break; 2998#endif 2999 case 30: 3000 /* FALLTHRU */ 3001 case 31: 3002 /* FALLTHRU */ 3003 case 32: 3004 /* FALLTHRU */ 3005 case 33: 3006 /* FALLTHRU */ 3007 case 34: 3008 /* FALLTHRU */ 3009 case 35: 3010 /* FALLTHRU */ 3011 case 36: 3012 /* FALLTHRU */ 3013 case 37: 3014 if_OPT_ISO_COLORS(screen, { 3015 xw->sgr_foreground = (op - 30); 3016 xw->sgr_extended = False; 3017 setExtendedFG(xw); 3018 }); 3019 break; 3020 case 38: 3021 /* This is more complicated than I'd like, but it should 3022 * properly eat all the parameters for unsupported modes. 3023 */ 3024 if_OPT_ISO_COLORS(screen, { 3025 if (parse_extended_colors(xw, &value, &item)) { 3026 xw->sgr_foreground = value; 3027 xw->sgr_extended = True; 3028 setExtendedFG(xw); 3029 } 3030 }); 3031 break; 3032 case 39: 3033 if_OPT_ISO_COLORS(screen, { 3034 reset_SGR_Foreground(xw); 3035 }); 3036 break; 3037 case 40: 3038 /* FALLTHRU */ 3039 case 41: 3040 /* FALLTHRU */ 3041 case 42: 3042 /* FALLTHRU */ 3043 case 43: 3044 /* FALLTHRU */ 3045 case 44: 3046 /* FALLTHRU */ 3047 case 45: 3048 /* FALLTHRU */ 3049 case 46: 3050 /* FALLTHRU */ 3051 case 47: 3052 if_OPT_ISO_COLORS(screen, { 3053 xw->sgr_background = (op - 40); 3054 setExtendedBG(xw); 3055 }); 3056 break; 3057 case 48: 3058 if_OPT_ISO_COLORS(screen, { 3059 if (parse_extended_colors(xw, &value, &item)) { 3060 xw->sgr_background = value; 3061 setExtendedBG(xw); 3062 } 3063 }); 3064 break; 3065 case 49: 3066 if_OPT_ISO_COLORS(screen, { 3067 reset_SGR_Background(xw); 3068 }); 3069 break; 3070 case 90: 3071 /* FALLTHRU */ 3072 case 91: 3073 /* FALLTHRU */ 3074 case 92: 3075 /* FALLTHRU */ 3076 case 93: 3077 /* FALLTHRU */ 3078 case 94: 3079 /* FALLTHRU */ 3080 case 95: 3081 /* FALLTHRU */ 3082 case 96: 3083 /* FALLTHRU */ 3084 case 97: 3085 if_OPT_AIX_COLORS(screen, { 3086 xw->sgr_foreground = (op - 90 + 8); 3087 xw->sgr_extended = False; 3088 setExtendedFG(xw); 3089 }); 3090 break; 3091 case 100: 3092#if !OPT_AIX_COLORS 3093 if_OPT_ISO_COLORS(screen, { 3094 reset_SGR_Foreground(xw); 3095 reset_SGR_Background(xw); 3096 }); 3097 break; 3098#endif 3099 case 101: 3100 /* FALLTHRU */ 3101 case 102: 3102 /* FALLTHRU */ 3103 case 103: 3104 /* FALLTHRU */ 3105 case 104: 3106 /* FALLTHRU */ 3107 case 105: 3108 /* FALLTHRU */ 3109 case 106: 3110 /* FALLTHRU */ 3111 case 107: 3112 if_OPT_AIX_COLORS(screen, { 3113 xw->sgr_background = (op - 100 + 8); 3114 setExtendedBG(xw); 3115 }); 3116 break; 3117 } 3118 } 3119 ResetState(sp); 3120 break; 3121 3122 /* DSR (except for the '?') is a superset of CPR */ 3123 case CASE_DSR: 3124 sp->private_function = True; 3125 3126 /* FALLTHRU */ 3127 case CASE_CPR: 3128 TRACE(("CASE_DSR - device status report\n")); 3129 count = 0; 3130 init_reply(ANSI_CSI); 3131 reply.a_pintro = CharOf(sp->private_function ? '?' : 0); 3132 reply.a_inters = 0; 3133 reply.a_final = 'n'; 3134 3135 switch (GetParam(0)) { 3136 case 5: 3137 TRACE(("...request operating status\n")); 3138 /* operating status */ 3139 reply.a_param[count++] = 0; /* (no malfunction ;-) */ 3140 break; 3141 case 6: 3142 TRACE(("...request %s\n", 3143 (sp->private_function 3144 ? "DECXCPR" 3145 : "CPR"))); 3146 /* CPR */ 3147 /* DECXCPR (with page=1) */ 3148 value = (screen->cur_row + 1); 3149 if ((xw->flags & ORIGIN) != 0) { 3150 value -= screen->top_marg; 3151 } 3152 reply.a_param[count++] = (ParmType) value; 3153 3154 value = (screen->cur_col + 1); 3155 if ((xw->flags & ORIGIN) != 0) { 3156 value -= screen->lft_marg; 3157 } 3158 reply.a_param[count++] = (ParmType) value; 3159 3160 if (sp->private_function 3161 && screen->vtXX_level >= 4) { /* VT420 */ 3162 reply.a_param[count++] = 1; 3163 } 3164 reply.a_final = 'R'; 3165 break; 3166 case 15: 3167 TRACE(("...request printer status\n")); 3168 if (sp->private_function 3169 && screen->vtXX_level >= 2) { /* VT220 */ 3170 reply.a_param[count++] = 13; /* no printer detected */ 3171 } 3172 break; 3173 case 25: 3174 TRACE(("...request UDK status\n")); 3175 if (sp->private_function 3176 && screen->vtXX_level >= 2) { /* VT220 */ 3177 reply.a_param[count++] = 20; /* UDK always unlocked */ 3178 } 3179 break; 3180 case 26: 3181 TRACE(("...request keyboard status\n")); 3182 if (sp->private_function 3183 && screen->vtXX_level >= 2) { /* VT220 */ 3184 reply.a_param[count++] = 27; 3185 reply.a_param[count++] = 1; /* North American */ 3186 if (screen->vtXX_level >= 4) { /* VT420 */ 3187 reply.a_param[count++] = 0; /* ready */ 3188 reply.a_param[count++] = 0; /* LK201 */ 3189 } 3190 } 3191 break; 3192 case 53: /* according to existing xterm handling */ 3193 /* FALLTHRU */ 3194 case 55: /* according to the VT330/VT340 Text Programming Manual */ 3195 TRACE(("...request locator status\n")); 3196 if (sp->private_function 3197 && screen->vtXX_level >= 2) { /* VT220 */ 3198#if OPT_DEC_LOCATOR 3199 reply.a_param[count++] = 50; /* locator ready */ 3200#else 3201 reply.a_param[count++] = 53; /* no locator */ 3202#endif 3203 } 3204 break; 3205 case 56: 3206 TRACE(("...request locator type\n")); 3207 if (sp->private_function 3208 && screen->vtXX_level >= 3) { /* VT330 (FIXME: what about VT220?) */ 3209 reply.a_param[count++] = 57; 3210#if OPT_DEC_LOCATOR 3211 reply.a_param[count++] = 1; /* mouse */ 3212#else 3213 reply.a_param[count++] = 0; /* unknown */ 3214#endif 3215 } 3216 break; 3217 case 62: 3218 TRACE(("...request DECMSR - macro space\n")); 3219 if (sp->private_function 3220 && screen->vtXX_level >= 4) { /* VT420 */ 3221 reply.a_pintro = 0; 3222 reply.a_radix[count] = 16; /* no data */ 3223 reply.a_param[count++] = 0; /* no space for macros */ 3224 reply.a_inters = '*'; 3225 reply.a_final = L_CURL; 3226 } 3227 break; 3228 case 63: 3229 TRACE(("...request DECCKSR - memory checksum\n")); 3230 /* DECCKSR - Memory checksum */ 3231 if (sp->private_function 3232 && screen->vtXX_level >= 4) { /* VT420 */ 3233 init_reply(ANSI_DCS); 3234 reply.a_param[count++] = (ParmType) GetParam(1); /* PID */ 3235 reply.a_delim = "!~"; /* delimiter */ 3236 reply.a_radix[count] = 16; /* use hex */ 3237 reply.a_param[count++] = 0; /* no data */ 3238 } 3239 break; 3240 case 75: 3241 TRACE(("...request data integrity\n")); 3242 if (sp->private_function 3243 && screen->vtXX_level >= 4) { /* VT420 */ 3244 reply.a_param[count++] = 70; /* no errors */ 3245 } 3246 break; 3247 case 85: 3248 TRACE(("...request multi-session configuration\n")); 3249 if (sp->private_function 3250 && screen->vtXX_level >= 4) { /* VT420 */ 3251 reply.a_param[count++] = 83; /* not configured */ 3252 } 3253 break; 3254 default: 3255 break; 3256 } 3257 3258 if ((reply.a_nparam = (ParmType) count) != 0) 3259 unparseseq(xw, &reply); 3260 3261 ResetState(sp); 3262 sp->private_function = False; 3263 break; 3264 3265 case CASE_MC: 3266 TRACE(("CASE_MC - media control\n")); 3267 xtermMediaControl(xw, GetParam(0), False); 3268 ResetState(sp); 3269 break; 3270 3271 case CASE_DEC_MC: 3272 TRACE(("CASE_DEC_MC - DEC media control\n")); 3273 xtermMediaControl(xw, GetParam(0), True); 3274 ResetState(sp); 3275 break; 3276 3277 case CASE_HP_MEM_LOCK: 3278 /* FALLTHRU */ 3279 case CASE_HP_MEM_UNLOCK: 3280 TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK) 3281 ? "CASE_HP_MEM_LOCK" 3282 : "CASE_HP_MEM_UNLOCK"))); 3283 if (screen->scroll_amt) 3284 FlushScroll(xw); 3285 if (sp->parsestate[c] == CASE_HP_MEM_LOCK) 3286 set_tb_margins(screen, screen->cur_row, screen->bot_marg); 3287 else 3288 set_tb_margins(screen, 0, screen->bot_marg); 3289 ResetState(sp); 3290 break; 3291 3292 case CASE_DECSTBM: 3293 TRACE(("CASE_DECSTBM - set scrolling region\n")); 3294 { 3295 int top; 3296 int bot; 3297 top = one_if_default(0); 3298 if (nparam < 2 || (bot = GetParam(1)) == DEFAULT 3299 || bot > MaxRows(screen) 3300 || bot == 0) 3301 bot = MaxRows(screen); 3302 if (bot > top) { 3303 if (screen->scroll_amt) 3304 FlushScroll(xw); 3305 set_tb_margins(screen, top - 1, bot - 1); 3306 CursorSet(screen, 0, 0, xw->flags); 3307 } 3308 ResetState(sp); 3309 } 3310 break; 3311 3312 case CASE_DECREQTPARM: 3313 TRACE(("CASE_DECREQTPARM\n")); 3314 if (screen->terminal_id < 200) { /* VT102 */ 3315 value = zero_if_default(0); 3316 if (value == 0 || value == 1) { 3317 init_reply(ANSI_CSI); 3318 reply.a_pintro = 0; 3319 reply.a_nparam = 7; 3320 reply.a_param[0] = (ParmType) (value + 2); 3321 reply.a_param[1] = 1; /* no parity */ 3322 reply.a_param[2] = 1; /* eight bits */ 3323 reply.a_param[3] = 128; /* transmit 38.4k baud */ 3324 reply.a_param[4] = 128; /* receive 38.4k baud */ 3325 reply.a_param[5] = 1; /* clock multiplier ? */ 3326 reply.a_param[6] = 0; /* STP flags ? */ 3327 reply.a_inters = 0; 3328 reply.a_final = 'x'; 3329 unparseseq(xw, &reply); 3330 } 3331 } 3332 ResetState(sp); 3333 break; 3334 3335 case CASE_DECSET: 3336 /* DECSET */ 3337#if OPT_VT52_MODE 3338 if (screen->vtXX_level != 0) 3339#endif 3340 dpmodes(xw, bitset); 3341 ResetState(sp); 3342#if OPT_TEK4014 3343 if (TEK4014_ACTIVE(xw)) { 3344 TRACE(("Tek4014 is now active...\n")); 3345 return False; 3346 } 3347#endif 3348 break; 3349 3350 case CASE_DECRST: 3351 /* DECRST */ 3352 dpmodes(xw, bitclr); 3353 init_groundtable(screen, sp); 3354 ResetState(sp); 3355 break; 3356 3357 case CASE_DECALN: 3358 TRACE(("CASE_DECALN - alignment test\n")); 3359 if (screen->cursor_state) 3360 HideCursor(); 3361 reset_margins(screen); 3362 CursorSet(screen, 0, 0, xw->flags); 3363 xtermParseRect(xw, 0, 0, &myRect); 3364 ScrnFillRectangle(xw, &myRect, 'E', 0, False); 3365 ResetState(sp); 3366 break; 3367 3368 case CASE_GSETS: 3369 TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c)); 3370 decode_scs(xw, sp->scstype, 0, (int) c); 3371 ResetState(sp); 3372 break; 3373 3374 case CASE_ANSI_SC: 3375 if (IsLeftRightMode(xw)) { 3376 int left; 3377 int right; 3378 3379 TRACE(("CASE_DECSLRM - set left and right margin\n")); 3380 left = one_if_default(0); 3381 if (nparam < 2 || (right = GetParam(1)) == DEFAULT 3382 || right > MaxCols(screen) 3383 || right == 0) 3384 right = MaxCols(screen); 3385 if (right > left) { 3386 set_lr_margins(screen, left - 1, right - 1); 3387 CursorSet(screen, 0, 0, xw->flags); 3388 } 3389 } else { 3390 TRACE(("CASE_ANSI_SC - save cursor\n")); 3391 CursorSave(xw); 3392 } 3393 ResetState(sp); 3394 break; 3395 3396 case CASE_DECSC: 3397 TRACE(("CASE_DECSC - save cursor\n")); 3398 CursorSave(xw); 3399 ResetState(sp); 3400 break; 3401 3402 case CASE_ANSI_RC: 3403 /* FALLTHRU */ 3404 case CASE_DECRC: 3405 TRACE(("CASE_%sRC - restore cursor\n", 3406 (sp->nextstate == CASE_DECRC) ? "DEC" : "ANSI_")); 3407 CursorRestore(xw); 3408 if_OPT_ISO_COLORS(screen, { 3409 setExtendedFG(xw); 3410 }); 3411 ResetState(sp); 3412 break; 3413 3414 case CASE_DECKPAM: 3415 TRACE(("CASE_DECKPAM\n")); 3416 xw->keyboard.flags |= MODE_DECKPAM; 3417 update_appkeypad(); 3418 ResetState(sp); 3419 break; 3420 3421 case CASE_DECKPNM: 3422 TRACE(("CASE_DECKPNM\n")); 3423 UIntClr(xw->keyboard.flags, MODE_DECKPAM); 3424 update_appkeypad(); 3425 ResetState(sp); 3426 break; 3427 3428 case CASE_CSI_QUOTE_STATE: 3429 sp->parsestate = csi_quo_table; 3430 break; 3431 3432#if OPT_BLINK_CURS 3433 case CASE_CSI_SPACE_STATE: 3434 sp->parsestate = csi_sp_table; 3435 break; 3436 3437 case CASE_DECSCUSR: 3438 TRACE(("CASE_DECSCUSR\n")); 3439 { 3440 Boolean change = True; 3441 Boolean blinks = screen->cursor_blink_esc; 3442 3443 HideCursor(); 3444 3445 switch (GetParam(0)) { 3446 case DEFAULT: 3447 /* FALLTHRU */ 3448 case DEFAULT_STYLE: 3449 /* FALLTHRU */ 3450 case BLINK_BLOCK: 3451 blinks = True; 3452 screen->cursor_shape = CURSOR_BLOCK; 3453 break; 3454 case STEADY_BLOCK: 3455 blinks = False; 3456 screen->cursor_shape = CURSOR_BLOCK; 3457 break; 3458 case BLINK_UNDERLINE: 3459 blinks = True; 3460 screen->cursor_shape = CURSOR_UNDERLINE; 3461 break; 3462 case STEADY_UNDERLINE: 3463 blinks = False; 3464 screen->cursor_shape = CURSOR_UNDERLINE; 3465 break; 3466 case BLINK_BAR: 3467 blinks = True; 3468 screen->cursor_shape = CURSOR_BAR; 3469 break; 3470 case STEADY_BAR: 3471 blinks = False; 3472 screen->cursor_shape = CURSOR_BAR; 3473 break; 3474 default: 3475 change = False; 3476 break; 3477 } 3478 TRACE(("cursor_shape:%d blinks:%s\n", 3479 screen->cursor_shape, BtoS(blinks))); 3480 if (change) { 3481 xtermSetCursorBox(screen); 3482 screen->cursor_blink_esc = blinks; 3483 UpdateCursorBlink(screen); 3484 } 3485 } 3486 ResetState(sp); 3487 break; 3488#endif 3489 3490#if OPT_SCROLL_LOCK 3491 case CASE_DECLL: 3492 TRACE(("CASE_DECLL\n")); 3493 if (nparam > 0) { 3494 for (count = 0; count < nparam; ++count) { 3495 int op = zero_if_default(count); 3496 switch (op) { 3497 case 0: 3498 case DEFAULT: 3499 xtermClearLEDs(screen); 3500 break; 3501 case 1: 3502 /* FALLTHRU */ 3503 case 2: 3504 /* FALLTHRU */ 3505 case 3: 3506 xtermShowLED(screen, 3507 (Cardinal) op, 3508 True); 3509 break; 3510 case 21: 3511 /* FALLTHRU */ 3512 case 22: 3513 /* FALLTHRU */ 3514 case 23: 3515 xtermShowLED(screen, 3516 (Cardinal) (op - 20), 3517 True); 3518 break; 3519 } 3520 } 3521 } else { 3522 xtermClearLEDs(screen); 3523 } 3524 ResetState(sp); 3525 break; 3526#endif 3527 3528#if OPT_VT52_MODE 3529 case CASE_VT52_FINISH: 3530 TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n", 3531 screen->terminal_id, 3532 screen->vtXX_level)); 3533 if (screen->terminal_id >= 100 3534 && screen->vtXX_level == 0) { 3535 sp->groundtable = 3536 sp->parsestate = ansi_table; 3537 /* 3538 * On restore, the terminal does not recognize DECRQSS for 3539 * DECSCL (per vttest). 3540 */ 3541 screen->vtXX_level = 1; 3542 screen->curgl = screen->vt52_save_curgl; 3543 screen->curgr = screen->vt52_save_curgr; 3544 screen->curss = screen->vt52_save_curss; 3545 memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets)); 3546 } 3547 break; 3548#endif 3549 3550 case CASE_ANSI_LEVEL_1: 3551 TRACE(("CASE_ANSI_LEVEL_1\n")); 3552 set_ansi_conformance(screen, 1); 3553 ResetState(sp); 3554 break; 3555 3556 case CASE_ANSI_LEVEL_2: 3557 TRACE(("CASE_ANSI_LEVEL_2\n")); 3558 set_ansi_conformance(screen, 2); 3559 ResetState(sp); 3560 break; 3561 3562 case CASE_ANSI_LEVEL_3: 3563 TRACE(("CASE_ANSI_LEVEL_3\n")); 3564 set_ansi_conformance(screen, 3); 3565 ResetState(sp); 3566 break; 3567 3568 case CASE_DECSCL: 3569 TRACE(("CASE_DECSCL(%d,%d)\n", GetParam(0), GetParam(1))); 3570 /* 3571 * This changes the emulation level, and is not recognized by 3572 * VT100s. 3573 */ 3574 if (screen->terminal_id >= 200) { 3575 /* 3576 * Disallow unrecognized parameters, as well as attempts to set 3577 * the operating level higher than the given terminal-id. 3578 */ 3579 if (GetParam(0) >= 61 3580 && GetParam(0) <= 60 + (screen->terminal_id / 100)) { 3581 int new_vtXX_level = GetParam(0) - 60; 3582 int case_value = zero_if_default(1); 3583 /* 3584 * VT300, VT420, VT520 manuals claim that DECSCL does a 3585 * hard reset (RIS). VT220 manual states that it is a soft 3586 * reset. Perhaps both are right (unlikely). Kermit says 3587 * it's soft. 3588 */ 3589 ReallyReset(xw, False, False); 3590 init_parser(xw, sp); 3591 screen->vtXX_level = new_vtXX_level; 3592 if (new_vtXX_level > 1) { 3593 switch (case_value) { 3594 case 1: 3595 show_8bit_control(False); 3596 break; 3597 case 0: 3598 case 2: 3599 show_8bit_control(True); 3600 break; 3601 } 3602 } 3603 } 3604 } 3605 ResetState(sp); 3606 break; 3607 3608 case CASE_DECSCA: 3609 TRACE(("CASE_DECSCA\n")); 3610 screen->protected_mode = DEC_PROTECT; 3611 if (GetParam(0) <= 0 || GetParam(0) == 2) { 3612 UIntClr(xw->flags, PROTECTED); 3613 TRACE(("...clear PROTECTED\n")); 3614 } else if (GetParam(0) == 1) { 3615 xw->flags |= PROTECTED; 3616 TRACE(("...set PROTECTED\n")); 3617 } 3618 ResetState(sp); 3619 break; 3620 3621 case CASE_DECSED: 3622 TRACE(("CASE_DECSED\n")); 3623 do_erase_display(xw, zero_if_default(0), DEC_PROTECT); 3624 ResetState(sp); 3625 break; 3626 3627 case CASE_DECSEL: 3628 TRACE(("CASE_DECSEL\n")); 3629 do_erase_line(xw, zero_if_default(0), DEC_PROTECT); 3630 ResetState(sp); 3631 break; 3632 3633 case CASE_GRAPHICS_ATTRIBUTES: 3634#if OPT_GRAPHICS 3635 TRACE(("CASE_GRAPHICS_ATTRIBUTES\n")); 3636 { 3637 /* request: item, action, value */ 3638 /* reply: item, status, value */ 3639 if (nparam != 3) { 3640 TRACE(("DATA_ERROR: malformed CASE_GRAPHICS_ATTRIBUTES request with %d parameters\n", nparam)); 3641 } else { 3642 int status = 3; 3643 int result = 0; 3644 int result2 = 0; 3645 3646 TRACE(("CASE_GRAPHICS_ATTRIBUTES request: %d, %d, %d\n", 3647 GetParam(0), GetParam(1), GetParam(2))); 3648 switch (GetParam(0)) { 3649 case 1: /* color register count */ 3650 switch (GetParam(1)) { 3651 case 1: /* read */ 3652 status = 0; 3653 result = (int) get_color_register_count(screen); 3654 break; 3655 case 2: /* reset */ 3656 screen->numcolorregisters = 0; 3657 status = 0; 3658 result = (int) get_color_register_count(screen); 3659 break; 3660 case 3: /* set */ 3661 if (GetParam(2) > 1 && 3662 (unsigned) GetParam(2) <= MAX_COLOR_REGISTERS) { 3663 screen->numcolorregisters = GetParam(2); 3664 status = 0; 3665 result = (int) get_color_register_count(screen); 3666 } 3667 break; 3668 case 4: /* read maximum */ 3669 status = 0; 3670 result = MAX_COLOR_REGISTERS; 3671 break; 3672 default: 3673 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES color register count request with unknown action parameter: %d\n", 3674 GetParam(1))); 3675 status = 2; 3676 break; 3677 } 3678 break; 3679 case 2: /* graphics geometry */ 3680 switch (GetParam(1)) { 3681 case 1: /* read */ 3682 status = 0; 3683 result = screen->graphics_max_wide; 3684 result2 = screen->graphics_max_high; 3685 break; 3686 case 2: /* reset */ 3687 /* FALLTHRU */ 3688 case 3: /* set */ 3689 /* FALLTHRU */ 3690 case 4: /* read maximum */ 3691 /* not implemented */ 3692 break; 3693 default: 3694 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES graphics geometry request with unknown action parameter: %d\n", 3695 GetParam(1))); 3696 status = 2; 3697 break; 3698 } 3699 break; 3700# if OPT_REGIS_GRAPHICS 3701 case 3: /* ReGIS geometry */ 3702 switch (GetParam(1)) { 3703 case 1: /* read */ 3704 status = 0; 3705 result = screen->graphics_regis_def_wide; 3706 result2 = screen->graphics_regis_def_high; 3707 break; 3708 case 2: /* reset */ 3709 /* FALLTHRU */ 3710 case 3: /* set */ 3711 /* FALLTHRU */ 3712 case 4: /* read maximum */ 3713 /* not implemented */ 3714 break; 3715 default: 3716 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES ReGIS geometry request with unknown action parameter: %d\n", 3717 GetParam(1))); 3718 status = 2; 3719 break; 3720 } 3721 break; 3722#endif 3723 default: 3724 TRACE(("DATA_ERROR: CASE_GRAPHICS_ATTRIBUTES request with unknown item parameter: %d\n", 3725 GetParam(0))); 3726 status = 1; 3727 break; 3728 } 3729 3730 init_reply(ANSI_CSI); 3731 reply.a_pintro = '?'; 3732 count = 0; 3733 reply.a_param[count++] = (ParmType) GetParam(0); 3734 reply.a_param[count++] = (ParmType) status; 3735 reply.a_param[count++] = (ParmType) result; 3736 if (GetParam(0) >= 2) 3737 reply.a_param[count++] = (ParmType) result2; 3738 reply.a_nparam = (ParmType) count; 3739 reply.a_inters = 0; 3740 reply.a_final = 'S'; 3741 unparseseq(xw, &reply); 3742 } 3743 } 3744#endif 3745 ResetState(sp); 3746 break; 3747 3748 case CASE_ST: 3749 TRACE(("CASE_ST: End of String (%lu bytes) (mode=%d)\n", 3750 (unsigned long) sp->string_used, 3751 sp->string_mode)); 3752 ResetState(sp); 3753 if (!sp->string_used) 3754 break; 3755 sp->string_area[--(sp->string_used)] = '\0'; 3756 switch (sp->string_mode) { 3757 case ANSI_APC: 3758 /* ignored */ 3759 break; 3760 case ANSI_DCS: 3761 do_dcs(xw, sp->string_area, sp->string_used); 3762 break; 3763 case ANSI_OSC: 3764 do_osc(xw, sp->string_area, sp->string_used, ANSI_ST); 3765 break; 3766 case ANSI_PM: 3767 /* ignored */ 3768 break; 3769 case ANSI_SOS: 3770 /* ignored */ 3771 break; 3772 default: 3773 TRACE(("unknown mode\n")); 3774 break; 3775 } 3776 break; 3777 3778 case CASE_SOS: 3779 TRACE(("CASE_SOS: Start of String\n")); 3780 if (ParseSOS(screen)) { 3781 sp->string_mode = ANSI_SOS; 3782 sp->parsestate = sos_table; 3783 } else { 3784 illegal_parse(xw, c, sp); 3785 } 3786 break; 3787 3788 case CASE_PM: 3789 TRACE(("CASE_PM: Privacy Message\n")); 3790 if (ParseSOS(screen)) { 3791 sp->string_mode = ANSI_PM; 3792 sp->parsestate = sos_table; 3793 } else { 3794 illegal_parse(xw, c, sp); 3795 } 3796 break; 3797 3798 case CASE_DCS: 3799 TRACE(("CASE_DCS: Device Control String\n")); 3800 sp->string_mode = ANSI_DCS; 3801 sp->parsestate = sos_table; 3802 break; 3803 3804 case CASE_APC: 3805 TRACE(("CASE_APC: Application Program Command\n")); 3806 if (ParseSOS(screen)) { 3807 sp->string_mode = ANSI_APC; 3808 sp->parsestate = sos_table; 3809 } else { 3810 illegal_parse(xw, c, sp); 3811 } 3812 break; 3813 3814 case CASE_SPA: 3815 TRACE(("CASE_SPA - start protected area\n")); 3816 screen->protected_mode = ISO_PROTECT; 3817 xw->flags |= PROTECTED; 3818 ResetState(sp); 3819 break; 3820 3821 case CASE_EPA: 3822 TRACE(("CASE_EPA - end protected area\n")); 3823 UIntClr(xw->flags, PROTECTED); 3824 ResetState(sp); 3825 break; 3826 3827 case CASE_SU: 3828 TRACE(("CASE_SU - scroll up\n")); 3829 xtermScroll(xw, one_if_default(0)); 3830 ResetState(sp); 3831 break; 3832 3833 case CASE_SL: /* ISO 6429, non-DEC */ 3834 TRACE(("CASE_SL - scroll left\n")); 3835 xtermScrollLR(xw, one_if_default(0), True); 3836 ResetState(sp); 3837 break; 3838 3839 case CASE_SR: /* ISO 6429, non-DEC */ 3840 TRACE(("CASE_SR - scroll right\n")); 3841 xtermScrollLR(xw, one_if_default(0), False); 3842 ResetState(sp); 3843 break; 3844 3845 case CASE_DECDC: 3846 TRACE(("CASE_DC - delete column\n")); 3847 if (screen->vtXX_level >= 4) { 3848 xtermColScroll(xw, one_if_default(0), True, screen->cur_col); 3849 } 3850 ResetState(sp); 3851 break; 3852 3853 case CASE_DECIC: 3854 TRACE(("CASE_IC - insert column\n")); 3855 if (screen->vtXX_level >= 4) { 3856 xtermColScroll(xw, one_if_default(0), False, screen->cur_col); 3857 } 3858 ResetState(sp); 3859 break; 3860 3861 case CASE_DECBI: 3862 TRACE(("CASE_BI - back index\n")); 3863 if (screen->vtXX_level >= 4) { 3864 xtermColIndex(xw, True); 3865 } 3866 ResetState(sp); 3867 break; 3868 3869 case CASE_DECFI: 3870 TRACE(("CASE_FI - forward index\n")); 3871 if (screen->vtXX_level >= 4) { 3872 xtermColIndex(xw, False); 3873 } 3874 ResetState(sp); 3875 break; 3876 3877 case CASE_IND: 3878 TRACE(("CASE_IND - index\n")); 3879 xtermIndex(xw, 1); 3880 do_xevents(); 3881 ResetState(sp); 3882 break; 3883 3884 case CASE_CPL: 3885 TRACE(("CASE_CPL - cursor prev line\n")); 3886 CursorPrevLine(xw, one_if_default(0)); 3887 ResetState(sp); 3888 break; 3889 3890 case CASE_CNL: 3891 TRACE(("CASE_CNL - cursor next line\n")); 3892 CursorNextLine(xw, one_if_default(0)); 3893 ResetState(sp); 3894 break; 3895 3896 case CASE_NEL: 3897 TRACE(("CASE_NEL\n")); 3898 xtermIndex(xw, 1); 3899 CarriageReturn(xw); 3900 ResetState(sp); 3901 break; 3902 3903 case CASE_HTS: 3904 TRACE(("CASE_HTS - horizontal tab set\n")); 3905 TabSet(xw->tabs, screen->cur_col); 3906 ResetState(sp); 3907 break; 3908 3909 case CASE_RI: 3910 TRACE(("CASE_RI - reverse index\n")); 3911 RevIndex(xw, 1); 3912 ResetState(sp); 3913 break; 3914 3915 case CASE_SS2: 3916 TRACE(("CASE_SS2\n")); 3917 screen->curss = 2; 3918 ResetState(sp); 3919 break; 3920 3921 case CASE_SS3: 3922 TRACE(("CASE_SS3\n")); 3923 screen->curss = 3; 3924 ResetState(sp); 3925 break; 3926 3927 case CASE_CSI_STATE: 3928 /* enter csi state */ 3929 InitParams(); 3930 SetParam(nparam++, DEFAULT); 3931 sp->parsestate = csi_table; 3932 break; 3933 3934 case CASE_ESC_SP_STATE: 3935 /* esc space */ 3936 sp->parsestate = esc_sp_table; 3937 break; 3938 3939 case CASE_CSI_EX_STATE: 3940 /* csi exclamation */ 3941 sp->parsestate = csi_ex_table; 3942 break; 3943 3944 case CASE_CSI_TICK_STATE: 3945 /* csi tick (') */ 3946 sp->parsestate = csi_tick_table; 3947 break; 3948 3949#if OPT_DEC_LOCATOR 3950 case CASE_DECEFR: 3951 TRACE(("CASE_DECEFR - Enable Filter Rectangle\n")); 3952 if (okSendMousePos(xw) == DEC_LOCATOR) { 3953 MotionOff(screen, xw); 3954 if ((screen->loc_filter_top = GetParam(0)) < 1) 3955 screen->loc_filter_top = LOC_FILTER_POS; 3956 if (nparam < 2 3957 || (screen->loc_filter_left = GetParam(1)) < 1) 3958 screen->loc_filter_left = LOC_FILTER_POS; 3959 if (nparam < 3 3960 || (screen->loc_filter_bottom = GetParam(2)) < 1) 3961 screen->loc_filter_bottom = LOC_FILTER_POS; 3962 if (nparam < 4 3963 || (screen->loc_filter_right = GetParam(3)) < 1) 3964 screen->loc_filter_right = LOC_FILTER_POS; 3965 InitLocatorFilter(xw); 3966 } 3967 ResetState(sp); 3968 break; 3969 3970 case CASE_DECELR: 3971 MotionOff(screen, xw); 3972 if (GetParam(0) <= 0 || GetParam(0) > 2) { 3973 screen->send_mouse_pos = MOUSE_OFF; 3974 TRACE(("DECELR - Disable Locator Reports\n")); 3975 } else { 3976 TRACE(("DECELR - Enable Locator Reports\n")); 3977 screen->send_mouse_pos = DEC_LOCATOR; 3978 xtermShowPointer(xw, True); 3979 if (GetParam(0) == 2) { 3980 screen->locator_reset = True; 3981 } else { 3982 screen->locator_reset = False; 3983 } 3984 if (nparam < 2 || GetParam(1) != 1) { 3985 screen->locator_pixels = False; 3986 } else { 3987 screen->locator_pixels = True; 3988 } 3989 screen->loc_filter = False; 3990 } 3991 ResetState(sp); 3992 break; 3993 3994 case CASE_DECSLE: 3995 TRACE(("DECSLE - Select Locator Events\n")); 3996 for (count = 0; count < nparam; ++count) { 3997 switch (zero_if_default(count)) { 3998 case 0: 3999 MotionOff(screen, xw); 4000 screen->loc_filter = False; 4001 screen->locator_events = 0; 4002 break; 4003 case 1: 4004 screen->locator_events |= LOC_BTNS_DN; 4005 break; 4006 case 2: 4007 UIntClr(screen->locator_events, LOC_BTNS_DN); 4008 break; 4009 case 3: 4010 screen->locator_events |= LOC_BTNS_UP; 4011 break; 4012 case 4: 4013 UIntClr(screen->locator_events, LOC_BTNS_UP); 4014 break; 4015 } 4016 } 4017 ResetState(sp); 4018 break; 4019 4020 case CASE_DECRQLP: 4021 TRACE(("DECRQLP - Request Locator Position\n")); 4022 if (GetParam(0) < 2) { 4023 /* Issue DECLRP Locator Position Report */ 4024 GetLocatorPosition(xw); 4025 } 4026 ResetState(sp); 4027 break; 4028#endif /* OPT_DEC_LOCATOR */ 4029 4030#if OPT_DEC_RECTOPS 4031 case CASE_CSI_DOLLAR_STATE: 4032 TRACE(("CASE_CSI_DOLLAR_STATE\n")); 4033 /* csi dollar ($) */ 4034 if (screen->vtXX_level >= 3) 4035 sp->parsestate = csi_dollar_table; 4036 else 4037 sp->parsestate = eigtable; 4038 break; 4039 4040 case CASE_CSI_STAR_STATE: 4041 TRACE(("CASE_CSI_STAR_STATE\n")); 4042 /* csi star (*) */ 4043 if (screen->vtXX_level >= 4) 4044 sp->parsestate = csi_star_table; 4045 else 4046 sp->parsestate = eigtable; 4047 break; 4048 4049 case CASE_DECRQCRA: 4050 if (screen->vtXX_level >= 4) { 4051 int checksum; 4052 4053 TRACE(("CASE_DECRQCRA - Request checksum of rectangular area\n")); 4054 xtermCheckRect(xw, ParamPair(0), &checksum); 4055 init_reply(ANSI_DCS); 4056 count = 0; 4057 reply.a_param[count++] = (ParmType) GetParam(1); /* PID */ 4058 reply.a_delim = "!~"; /* delimiter */ 4059 reply.a_radix[count] = 16; 4060 reply.a_param[count++] = (ParmType) checksum; 4061 reply.a_nparam = (ParmType) count; 4062 unparseseq(xw, &reply); 4063 } 4064 ResetState(sp); 4065 break; 4066 4067 case CASE_DECCRA: 4068 if (screen->vtXX_level >= 4) { 4069 TRACE(("CASE_DECCRA - Copy rectangular area\n")); 4070 xtermParseRect(xw, ParamPair(0), &myRect); 4071 ScrnCopyRectangle(xw, &myRect, ParamPair(5)); 4072 } 4073 ResetState(sp); 4074 break; 4075 4076 case CASE_DECERA: 4077 if (screen->vtXX_level >= 4) { 4078 TRACE(("CASE_DECERA - Erase rectangular area\n")); 4079 xtermParseRect(xw, ParamPair(0), &myRect); 4080 ScrnFillRectangle(xw, &myRect, ' ', 0, True); 4081 } 4082 ResetState(sp); 4083 break; 4084 4085 case CASE_DECFRA: 4086 if (screen->vtXX_level >= 4) { 4087 value = zero_if_default(0); 4088 4089 TRACE(("CASE_DECFRA - Fill rectangular area\n")); 4090 if (nparam > 0 4091 && ((value >= 32 && value <= 126) 4092 || (value >= 160 && value <= 255))) { 4093 xtermParseRect(xw, ParamPair(1), &myRect); 4094 ScrnFillRectangle(xw, &myRect, value, xw->flags, True); 4095 } 4096 } 4097 ResetState(sp); 4098 break; 4099 4100 case CASE_DECSERA: 4101 if (screen->vtXX_level >= 4) { 4102 TRACE(("CASE_DECSERA - Selective erase rectangular area\n")); 4103 xtermParseRect(xw, ParamPair(0), &myRect); 4104 ScrnWipeRectangle(xw, &myRect); 4105 } 4106 ResetState(sp); 4107 break; 4108 4109 case CASE_DECSACE: 4110 TRACE(("CASE_DECSACE - Select attribute change extent\n")); 4111 screen->cur_decsace = zero_if_default(0); 4112 ResetState(sp); 4113 break; 4114 4115 case CASE_DECCARA: 4116 if (screen->vtXX_level >= 4) { 4117 TRACE(("CASE_DECCARA - Change attributes in rectangular area\n")); 4118 xtermParseRect(xw, ParamPair(0), &myRect); 4119 ScrnMarkRectangle(xw, &myRect, False, ParamPair(4)); 4120 } 4121 ResetState(sp); 4122 break; 4123 4124 case CASE_DECRARA: 4125 if (screen->vtXX_level >= 4) { 4126 TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n")); 4127 xtermParseRect(xw, ParamPair(0), &myRect); 4128 ScrnMarkRectangle(xw, &myRect, True, ParamPair(4)); 4129 } 4130 ResetState(sp); 4131 break; 4132 4133 case CASE_RQM: 4134 TRACE(("CASE_RQM\n")); 4135 do_rpm(xw, ParamPair(0)); 4136 ResetState(sp); 4137 break; 4138 4139 case CASE_DECRQM: 4140 TRACE(("CASE_DECRQM\n")); 4141 do_decrpm(xw, ParamPair(0)); 4142 ResetState(sp); 4143 break; 4144 4145 case CASE_CSI_DEC_DOLLAR_STATE: 4146 TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n")); 4147 /* csi ? dollar ($) */ 4148 sp->parsestate = csi_dec_dollar_table; 4149 break; 4150#else 4151 case CASE_CSI_DOLLAR_STATE: 4152 /* csi dollar ($) */ 4153 sp->parsestate = eigtable; 4154 break; 4155 4156 case CASE_CSI_STAR_STATE: 4157 /* csi dollar (*) */ 4158 sp->parsestate = eigtable; 4159 break; 4160 4161 case CASE_CSI_DEC_DOLLAR_STATE: 4162 /* csi ? dollar ($) */ 4163 sp->parsestate = eigtable; 4164 break; 4165#endif /* OPT_DEC_RECTOPS */ 4166 4167 case CASE_S7C1T: 4168 TRACE(("CASE_S7C1T\n")); 4169 if (screen->vtXX_level >= 2) { 4170 show_8bit_control(False); 4171 ResetState(sp); 4172 } 4173 break; 4174 4175 case CASE_S8C1T: 4176 TRACE(("CASE_S8C1T\n")); 4177 if (screen->vtXX_level >= 2) { 4178#if OPT_VT52_MODE 4179 if (screen->vtXX_level <= 1) 4180 break; 4181#endif 4182 show_8bit_control(True); 4183 ResetState(sp); 4184 } 4185 break; 4186 4187 case CASE_OSC: 4188 TRACE(("CASE_OSC: Operating System Command\n")); 4189 sp->parsestate = sos_table; 4190 sp->string_mode = ANSI_OSC; 4191 break; 4192 4193 case CASE_RIS: 4194 TRACE(("CASE_RIS\n")); 4195 VTReset(xw, True, True); 4196 /* NOTREACHED */ 4197 4198 case CASE_DECSTR: 4199 TRACE(("CASE_DECSTR\n")); 4200 VTReset(xw, False, False); 4201 /* NOTREACHED */ 4202 4203 case CASE_REP: 4204 TRACE(("CASE_REP\n")); 4205 if (sp->lastchar >= 0 && 4206 sp->lastchar < 256 && 4207 sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) { 4208 IChar repeated[2]; 4209 count = one_if_default(0); 4210 repeated[0] = (IChar) sp->lastchar; 4211 while (count-- > 0) { 4212 dotext(xw, 4213 screen->gsets[(int) (screen->curgl)], 4214 repeated, 1); 4215 } 4216 } 4217 ResetState(sp); 4218 break; 4219 4220 case CASE_LS2: 4221 TRACE(("CASE_LS2\n")); 4222 screen->curgl = 2; 4223 ResetState(sp); 4224 break; 4225 4226 case CASE_LS3: 4227 TRACE(("CASE_LS3\n")); 4228 screen->curgl = 3; 4229 ResetState(sp); 4230 break; 4231 4232 case CASE_LS3R: 4233 TRACE(("CASE_LS3R\n")); 4234 screen->curgr = 3; 4235 ResetState(sp); 4236 break; 4237 4238 case CASE_LS2R: 4239 TRACE(("CASE_LS2R\n")); 4240 screen->curgr = 2; 4241 ResetState(sp); 4242 break; 4243 4244 case CASE_LS1R: 4245 TRACE(("CASE_LS1R\n")); 4246 screen->curgr = 1; 4247 ResetState(sp); 4248 break; 4249 4250 case CASE_XTERM_SAVE: 4251 savemodes(xw); 4252 ResetState(sp); 4253 break; 4254 4255 case CASE_XTERM_RESTORE: 4256 restoremodes(xw); 4257 ResetState(sp); 4258 break; 4259 4260 case CASE_XTERM_WINOPS: 4261 TRACE(("CASE_XTERM_WINOPS\n")); 4262 window_ops(xw); 4263 ResetState(sp); 4264 break; 4265#if OPT_WIDE_CHARS 4266 case CASE_ESC_PERCENT: 4267 TRACE(("CASE_ESC_PERCENT\n")); 4268 sp->parsestate = esc_pct_table; 4269 break; 4270 4271 case CASE_UTF8: 4272 /* If we did not set UTF-8 mode from resource or the 4273 * command-line, allow it to be enabled/disabled by 4274 * control sequence. 4275 */ 4276 TRACE(("CASE_UTF8 wide:%d, utf8:%d, req:%s\n", 4277 screen->wide_chars, 4278 screen->utf8_mode, 4279 BtoS(c == 'G'))); 4280 if ((!screen->wide_chars) && (c == 'G')) { 4281 WriteNow(); 4282 ChangeToWide(xw); 4283 } 4284 if (screen->wide_chars 4285 && !screen->utf8_always) { 4286 switchPtyData(screen, c == 'G'); 4287 TRACE(("UTF8 mode %s\n", 4288 BtoS(screen->utf8_mode))); 4289 } else { 4290 TRACE(("UTF8 mode NOT turned %s (%s)\n", 4291 BtoS(c == 'G'), 4292 (screen->utf8_mode == uAlways) 4293 ? "UTF-8 mode set from command-line" 4294 : "wideChars resource was not set")); 4295 } 4296 ResetState(sp); 4297 break; 4298 4299 case CASE_SCS_PERCENT: 4300 TRACE(("CASE_SCS_PERCENT\n")); 4301 sp->parsestate = scs_pct_table; 4302 break; 4303 4304 case CASE_GSETS_PERCENT: 4305 TRACE(("CASE_GSETS_PERCENT(%d) = '%c'\n", sp->scstype, c)); 4306 decode_scs(xw, sp->scstype, '%', (int) c); 4307 ResetState(sp); 4308 break; 4309#endif 4310#if OPT_MOD_FKEYS 4311 case CASE_SET_MOD_FKEYS: 4312 TRACE(("CASE_SET_MOD_FKEYS\n")); 4313 if (nparam >= 1) { 4314 set_mod_fkeys(xw, 4315 GetParam(0), 4316 ((nparam > 1) 4317 ? GetParam(1) 4318 : DEFAULT), 4319 True); 4320 } else { 4321 for (value = 1; value <= 5; ++value) 4322 set_mod_fkeys(xw, value, DEFAULT, True); 4323 } 4324 break; 4325 case CASE_SET_MOD_FKEYS0: 4326 TRACE(("CASE_SET_MOD_FKEYS0\n")); 4327 if (nparam >= 1 && GetParam(0) != DEFAULT) { 4328 set_mod_fkeys(xw, GetParam(0), -1, False); 4329 } else { 4330 xw->keyboard.modify_now.function_keys = -1; 4331 } 4332 break; 4333#endif 4334 case CASE_HIDE_POINTER: 4335 TRACE(("CASE_HIDE_POINTER\n")); 4336 if (nparam >= 1 && GetParam(0) != DEFAULT) { 4337 screen->pointer_mode = GetParam(0); 4338 } else { 4339 screen->pointer_mode = DEF_POINTER_MODE; 4340 } 4341 break; 4342 4343 case CASE_SM_TITLE: 4344 TRACE(("CASE_SM_TITLE\n")); 4345 if (nparam >= 1) { 4346 int n; 4347 for (n = 0; n < nparam; ++n) { 4348 if (GetParam(n) != DEFAULT) 4349 screen->title_modes |= (1 << GetParam(n)); 4350 } 4351 } else { 4352 screen->title_modes = DEF_TITLE_MODES; 4353 } 4354 TRACE(("...title_modes %#x\n", screen->title_modes)); 4355 break; 4356 4357 case CASE_RM_TITLE: 4358 TRACE(("CASE_RM_TITLE\n")); 4359 if (nparam >= 1) { 4360 int n; 4361 for (n = 0; n < nparam; ++n) { 4362 if (GetParam(n) != DEFAULT) 4363 screen->title_modes &= ~(1 << GetParam(n)); 4364 } 4365 } else { 4366 screen->title_modes = DEF_TITLE_MODES; 4367 } 4368 TRACE(("...title_modes %#x\n", screen->title_modes)); 4369 break; 4370 4371 case CASE_CSI_IGNORE: 4372 sp->parsestate = cigtable; 4373 break; 4374 4375 case CASE_DECSWBV: 4376 TRACE(("CASE_DECSWBV\n")); 4377 switch (zero_if_default(0)) { 4378 case 2: 4379 /* FALLTHRU */ 4380 case 3: 4381 /* FALLTHRU */ 4382 case 4: 4383 screen->warningVolume = bvLow; 4384 break; 4385 case 5: 4386 /* FALLTHRU */ 4387 case 6: 4388 /* FALLTHRU */ 4389 case 7: 4390 /* FALLTHRU */ 4391 case 8: 4392 screen->warningVolume = bvHigh; 4393 break; 4394 default: 4395 screen->warningVolume = bvOff; 4396 break; 4397 } 4398 TRACE(("...warningVolume %d\n", screen->warningVolume)); 4399 ResetState(sp); 4400 break; 4401 4402 case CASE_DECSMBV: 4403 TRACE(("CASE_DECSMBV\n")); 4404 switch (zero_if_default(0)) { 4405 case 2: 4406 /* FALLTHRU */ 4407 case 3: 4408 /* FALLTHRU */ 4409 case 4: 4410 screen->marginVolume = bvLow; 4411 break; 4412 case 0: 4413 /* FALLTHRU */ 4414 case 5: 4415 /* FALLTHRU */ 4416 case 6: 4417 /* FALLTHRU */ 4418 case 7: 4419 /* FALLTHRU */ 4420 case 8: 4421 screen->marginVolume = bvHigh; 4422 break; 4423 default: 4424 screen->marginVolume = bvOff; 4425 break; 4426 } 4427 TRACE(("...marginVolume %d\n", screen->marginVolume)); 4428 ResetState(sp); 4429 break; 4430 } 4431 if (sp->parsestate == sp->groundtable) 4432 sp->lastchar = thischar; 4433 } while (0); 4434 4435#if OPT_WIDE_CHARS 4436 screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse) 4437 && (sp->parsestate != sos_table)); 4438#endif 4439 4440 return True; 4441} 4442 4443static void 4444VTparse(XtermWidget xw) 4445{ 4446 /* We longjmp back to this point in VTReset() */ 4447 (void) setjmp(vtjmpbuf); 4448 init_parser(xw, &myState); 4449 4450 do { 4451 } while (doparsing(xw, doinput(), &myState)); 4452} 4453 4454static Char *v_buffer; /* pointer to physical buffer */ 4455static Char *v_bufstr = NULL; /* beginning of area to write */ 4456static Char *v_bufptr; /* end of area to write */ 4457static Char *v_bufend; /* end of physical buffer */ 4458 4459/* Write data to the pty as typed by the user, pasted with the mouse, 4460 or generated by us in response to a query ESC sequence. */ 4461 4462void 4463v_write(int f, const Char *data, unsigned len) 4464{ 4465 TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len))); 4466 if (v_bufstr == NULL) { 4467 if (len > 0) { 4468 v_buffer = (Char *) XtMalloc((Cardinal) len); 4469 v_bufstr = v_buffer; 4470 v_bufptr = v_buffer; 4471 v_bufend = v_buffer + len; 4472 } 4473 if (v_bufstr == NULL) { 4474 return; 4475 } 4476 } 4477 if_DEBUG({ 4478 fprintf(stderr, "v_write called with %u bytes (%ld left over)", 4479 len, (long) (v_bufptr - v_bufstr)); 4480 if (len > 1 && len < 10) 4481 fprintf(stderr, " \"%.*s\"", len, (const char *) data); 4482 fprintf(stderr, "\n"); 4483 }); 4484 4485#ifdef VMS 4486 if ((1 << f) != pty_mask) { 4487 tt_write((const char *) data, len); 4488 return; 4489 } 4490#else /* VMS */ 4491 if (!FD_ISSET(f, &pty_mask)) { 4492 IGNORE_RC(write(f, (const char *) data, (size_t) len)); 4493 return; 4494 } 4495#endif /* VMS */ 4496 4497 /* 4498 * Append to the block we already have. 4499 * Always doing this simplifies the code, and 4500 * isn't too bad, either. If this is a short 4501 * block, it isn't too expensive, and if this is 4502 * a long block, we won't be able to write it all 4503 * anyway. 4504 */ 4505 4506 if (len > 0) { 4507#if OPT_DABBREV 4508 TScreenOf(term)->dabbrev_working = False; /* break dabbrev sequence */ 4509#endif 4510 if (v_bufend < v_bufptr + len) { /* we've run out of room */ 4511 if (v_bufstr != v_buffer) { 4512 /* there is unused space, move everything down */ 4513 /* possibly overlapping memmove here */ 4514 if_DEBUG({ 4515 fprintf(stderr, "moving data down %ld\n", 4516 (long) (v_bufstr - v_buffer)); 4517 }); 4518 memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr)); 4519 v_bufptr -= v_bufstr - v_buffer; 4520 v_bufstr = v_buffer; 4521 } 4522 if (v_bufend < v_bufptr + len) { 4523 /* still won't fit: get more space */ 4524 /* Don't use XtRealloc because an error is not fatal. */ 4525 unsigned size = (unsigned) (v_bufptr - v_buffer); 4526 v_buffer = TypeRealloc(Char, size + len, v_buffer); 4527 if (v_buffer) { 4528 if_DEBUG({ 4529 fprintf(stderr, "expanded buffer to %u\n", 4530 size + len); 4531 }); 4532 v_bufstr = v_buffer; 4533 v_bufptr = v_buffer + size; 4534 v_bufend = v_bufptr + len; 4535 } else { 4536 /* no memory: ignore entire write request */ 4537 xtermWarning("cannot allocate buffer space\n"); 4538 v_buffer = v_bufstr; /* restore clobbered pointer */ 4539 } 4540 } 4541 } 4542 if (v_bufend >= v_bufptr + len) { 4543 /* new stuff will fit */ 4544 memmove(v_bufptr, data, (size_t) len); 4545 v_bufptr += len; 4546 } 4547 } 4548 4549 /* 4550 * Write out as much of the buffer as we can. 4551 * Be careful not to overflow the pty's input silo. 4552 * We are conservative here and only write 4553 * a small amount at a time. 4554 * 4555 * If we can't push all the data into the pty yet, we expect write 4556 * to return a non-negative number less than the length requested 4557 * (if some data written) or -1 and set errno to EAGAIN, 4558 * EWOULDBLOCK, or EINTR (if no data written). 4559 * 4560 * (Not all systems do this, sigh, so the code is actually 4561 * a little more forgiving.) 4562 */ 4563 4564#define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */ 4565 4566 if (v_bufptr > v_bufstr) { 4567 int riten; 4568 4569#ifdef VMS 4570 riten = tt_write(v_bufstr, 4571 ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE) 4572 ? v_bufptr - v_bufstr 4573 : VMS_TERM_BUFFER_SIZE)); 4574 if (riten == 0) 4575 return (riten); 4576#else /* VMS */ 4577 riten = (int) write(f, v_bufstr, 4578 (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE) 4579 ? v_bufptr - v_bufstr 4580 : MAX_PTY_WRITE)); 4581 if (riten < 0) 4582#endif /* VMS */ 4583 { 4584 if_DEBUG({ 4585 perror("write"); 4586 }); 4587 riten = 0; 4588 } 4589 if_DEBUG({ 4590 fprintf(stderr, "write called with %ld, wrote %d\n", 4591 ((long) ((v_bufptr - v_bufstr) <= MAX_PTY_WRITE) 4592 ? (long) (v_bufptr - v_bufstr) 4593 : MAX_PTY_WRITE), 4594 riten); 4595 }); 4596 v_bufstr += riten; 4597 if (v_bufstr >= v_bufptr) /* we wrote it all */ 4598 v_bufstr = v_bufptr = v_buffer; 4599 } 4600 4601 /* 4602 * If we have lots of unused memory allocated, return it 4603 */ 4604 if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */ 4605 /* save pointers across realloc */ 4606 int start = (int) (v_bufstr - v_buffer); 4607 int size = (int) (v_bufptr - v_buffer); 4608 unsigned allocsize = (unsigned) (size ? size : 1); 4609 4610 v_buffer = TypeRealloc(Char, allocsize, v_buffer); 4611 if (v_buffer) { 4612 v_bufstr = v_buffer + start; 4613 v_bufptr = v_buffer + size; 4614 v_bufend = v_buffer + allocsize; 4615 if_DEBUG({ 4616 fprintf(stderr, "shrunk buffer to %u\n", allocsize); 4617 }); 4618 } else { 4619 /* should we print a warning if couldn't return memory? */ 4620 v_buffer = v_bufstr - start; /* restore clobbered pointer */ 4621 } 4622 } 4623} 4624 4625static void 4626updateCursor(TScreen *screen) 4627{ 4628 if (screen->cursor_set != screen->cursor_state) { 4629 if (screen->cursor_set) 4630 ShowCursor(); 4631 else 4632 HideCursor(); 4633 } 4634} 4635 4636#if OPT_BLINK_CURS || OPT_BLINK_TEXT 4637static void 4638reallyStopBlinking(TScreen *screen) 4639{ 4640 if (screen->cursor_state == BLINKED_OFF) { 4641 /* force cursor to display if it is enabled */ 4642 screen->cursor_state = !screen->cursor_set; 4643 updateCursor(screen); 4644 xevents(); 4645 } 4646} 4647#endif 4648 4649#ifdef VMS 4650#define ptymask() (v_bufptr > v_bufstr ? pty_mask : 0) 4651 4652static void 4653in_put(XtermWidget xw) 4654{ 4655 static PtySelect select_mask; 4656 static PtySelect write_mask; 4657 int update = VTbuffer->update; 4658 int size; 4659 4660 int status; 4661 Dimension replyWidth, replyHeight; 4662 XtGeometryResult stat; 4663 4664 TScreen *screen = TScreenOf(xw); 4665 char *cp; 4666 int i; 4667 4668 select_mask = pty_mask; /* force initial read */ 4669 for (;;) { 4670 4671 /* if the terminal changed size, resize the widget */ 4672 if (tt_changed) { 4673 tt_changed = False; 4674 4675 stat = REQ_RESIZE((Widget) xw, 4676 ((Dimension) FontWidth(screen) 4677 * (tt_width) 4678 + 2 * screen->border 4679 + screen->fullVwin.sb_info.width), 4680 ((Dimension) FontHeight(screen) 4681 * (tt_length) 4682 + 2 * screen->border), 4683 &replyWidth, &replyHeight); 4684 4685 if (stat == XtGeometryYes || stat == XtGeometryDone) { 4686 xw->core.width = replyWidth; 4687 xw->core.height = replyHeight; 4688 4689 ScreenResize(xw, replyWidth, replyHeight, &xw->flags); 4690 } 4691 repairSizeHints(); 4692 } 4693 4694 if (screen->eventMode == NORMAL 4695 && readPtyData(xw, &select_mask, VTbuffer)) { 4696 if (screen->scrollWidget 4697 && screen->scrollttyoutput 4698 && screen->topline < 0) 4699 /* Scroll to bottom */ 4700 WindowScroll(xw, 0, False); 4701 break; 4702 } 4703 if (screen->scroll_amt) 4704 FlushScroll(xw); 4705 if (screen->cursor_set && CursorMoved(screen)) { 4706 if (screen->cursor_state) 4707 HideCursor(); 4708 ShowCursor(); 4709#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 4710 PreeditPosition(xw); 4711#endif 4712 } else { 4713 updateCursor(screen); 4714 } 4715 4716 if (QLength(screen->display)) { 4717 select_mask = X_mask; 4718 } else { 4719 write_mask = ptymask(); 4720 XFlush(screen->display); 4721 select_mask = Select_mask; 4722 if (screen->eventMode != NORMAL) 4723 select_mask = X_mask; 4724 } 4725 if (write_mask & ptymask()) { 4726 v_write(screen->respond, 0, 0); /* flush buffer */ 4727 } 4728 4729 if (select_mask & X_mask) { 4730 xevents(); 4731 if (VTbuffer->update != update) 4732 break; 4733 } 4734 } 4735} 4736#else /* VMS */ 4737 4738static void 4739in_put(XtermWidget xw) 4740{ 4741 static PtySelect select_mask; 4742 static PtySelect write_mask; 4743 4744 TScreen *screen = TScreenOf(xw); 4745 int i; 4746 int update = VTbuffer->update; 4747#if OPT_DOUBLE_BUFFER 4748 int should_wait = 1; 4749#endif 4750 4751 static struct timeval select_timeout; 4752 4753#if OPT_BLINK_CURS 4754 /* 4755 * Compute the timeout for the blinking cursor to be much smaller than 4756 * the "on" or "off" interval. 4757 */ 4758 int tick = ((screen->blink_on < screen->blink_off) 4759 ? screen->blink_on 4760 : screen->blink_off); 4761 tick *= (1000 / 8); /* 1000 for msec/usec, 8 for "much" smaller */ 4762 if (tick < 1) 4763 tick = 1; 4764#endif 4765 4766 for (;;) { 4767 int size; 4768 int time_select; 4769 4770 if (screen->eventMode == NORMAL 4771 && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) { 4772 if (screen->scrollWidget 4773 && screen->scrollttyoutput 4774 && screen->topline < 0) 4775 WindowScroll(xw, 0, False); /* Scroll to bottom */ 4776 /* stop speed reading at some point to look for X stuff */ 4777 TRACE(("VTbuffer uses %ld/%d\n", 4778 (long) (VTbuffer->last - VTbuffer->buffer), 4779 BUF_SIZE)); 4780 if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) { 4781 FD_CLR(screen->respond, &select_mask); 4782 break; 4783 } 4784#if OPT_DOUBLE_BUFFER 4785 if (should_wait) { 4786 /* wait 25 msec for potential extra data (avoids some bogus flickering) */ 4787 /* that's only 40 FPS but hey, it's still lower than the input lag on some consoles! :) */ 4788 usleep(25000); 4789 should_wait = 0; 4790 } 4791 select_timeout.tv_sec = 0; 4792 i = Select(max_plus1, &select_mask, &write_mask, 0, 4793 &select_timeout); 4794 if (i > 0 && FD_ISSET(screen->respond, &select_mask)) 4795 continue; 4796 else 4797 break; 4798#elif defined(HAVE_SCHED_YIELD) 4799 /* 4800 * If we've read a full (small/fragment) buffer, let the operating 4801 * system have a turn, and we'll resume reading until we've either 4802 * read only a fragment of the buffer, or we've filled the large 4803 * buffer (see above). Doing this helps keep up with large bursts 4804 * of output. 4805 */ 4806 if (size == FRG_SIZE) { 4807 select_timeout.tv_sec = 0; 4808 i = Select(max_plus1, &select_mask, &write_mask, 0, 4809 &select_timeout); 4810 if (i > 0 && FD_ISSET(screen->respond, &select_mask)) { 4811 sched_yield(); 4812 } else 4813 break; 4814 } else { 4815 break; 4816 } 4817#else 4818 (void) size; /* unused in this branch */ 4819 break; 4820#endif 4821 } 4822 /* update the screen */ 4823 if (screen->scroll_amt) 4824 FlushScroll(xw); 4825 if (screen->cursor_set && CursorMoved(screen)) { 4826 if (screen->cursor_state) 4827 HideCursor(); 4828 ShowCursor(); 4829#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 4830 PreeditPosition(xw); 4831#endif 4832 } else { 4833 updateCursor(screen); 4834 } 4835 4836 XFlush(screen->display); /* always flush writes before waiting */ 4837 4838 /* Update the masks and, unless X events are already in the queue, 4839 wait for I/O to be possible. */ 4840 XFD_COPYSET(&Select_mask, &select_mask); 4841 /* in selection mode xterm does not read pty */ 4842 if (screen->eventMode != NORMAL) 4843 FD_CLR(screen->respond, &select_mask); 4844 4845 if (v_bufptr > v_bufstr) { 4846 XFD_COPYSET(&pty_mask, &write_mask); 4847 } else 4848 FD_ZERO(&write_mask); 4849 select_timeout.tv_sec = 0; 4850 time_select = 0; 4851 4852 /* 4853 * if there's either an XEvent or an XtTimeout pending, just take 4854 * a quick peek, i.e. timeout from the select() immediately. If 4855 * there's nothing pending, let select() block a little while, but 4856 * for a shorter interval than the arrow-style scrollbar timeout. 4857 * The blocking is optional, because it tends to increase the load 4858 * on the host. 4859 */ 4860 if (xtermAppPending()) { 4861 select_timeout.tv_usec = 0; 4862 time_select = 1; 4863 } else if (screen->awaitInput) { 4864 select_timeout.tv_usec = 50000; 4865 time_select = 1; 4866#if OPT_BLINK_CURS 4867 } else if ((screen->blink_timer != 0 && 4868 ((screen->select & FOCUS) || screen->always_highlight)) || 4869 (screen->cursor_state == BLINKED_OFF)) { 4870 select_timeout.tv_usec = tick; 4871 while (select_timeout.tv_usec > 1000000) { 4872 select_timeout.tv_usec -= 1000000; 4873 select_timeout.tv_sec++; 4874 } 4875 time_select = 1; 4876#endif 4877#if OPT_SESSION_MGT 4878 } else if (resource.sessionMgt) { 4879 if (ice_fd >= 0) 4880 FD_SET(ice_fd, &select_mask); 4881#endif 4882 } 4883 if (need_cleanup) 4884 NormalExit(); 4885#if OPT_DOUBLE_BUFFER 4886 if (screen->needSwap) { 4887 XdbeSwapInfo swap; 4888 swap.swap_window = VWindow(screen); 4889 swap.swap_action = XdbeCopied; 4890 XdbeSwapBuffers(XtDisplay(term), &swap, 1); 4891 XFlush(XtDisplay(xw)); 4892 screen->needSwap = 0; 4893 } 4894#endif 4895 i = Select(max_plus1, &select_mask, &write_mask, 0, 4896 (time_select ? &select_timeout : 0)); 4897 if (i < 0) { 4898 if (errno != EINTR) 4899 SysError(ERROR_SELECT); 4900 continue; 4901 } 4902 4903 /* if there is room to write more data to the pty, go write more */ 4904 if (FD_ISSET(screen->respond, &write_mask)) { 4905 v_write(screen->respond, (Char *) 0, 0); /* flush buffer */ 4906 } 4907 4908 /* if there are X events already in our queue, it 4909 counts as being readable */ 4910 if (xtermAppPending() || 4911 FD_ISSET(ConnectionNumber(screen->display), &select_mask)) { 4912 xevents(); 4913 if (VTbuffer->update != update) /* HandleInterpret */ 4914 break; 4915 } 4916 4917 } 4918} 4919#endif /* VMS */ 4920 4921static IChar 4922doinput(void) 4923{ 4924 TScreen *screen = TScreenOf(term); 4925 4926 while (!morePtyData(screen, VTbuffer)) 4927 in_put(term); 4928 return nextPtyData(screen, VTbuffer); 4929} 4930 4931#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 4932/* 4933 * For OverTheSpot, client has to inform the position for XIM preedit. 4934 */ 4935static void 4936PreeditPosition(XtermWidget xw) 4937{ 4938 TInput *input = lookupTInput(xw, (Widget) xw); 4939 TScreen *screen = TScreenOf(xw); 4940 CLineData *ld; 4941 XPoint spot; 4942 XVaNestedList list; 4943 4944 if (input && input->xic 4945 && (ld = getLineData(screen, screen->cur_row)) != 0) { 4946 spot.x = (short) LineCursorX(screen, ld, screen->cur_col); 4947 spot.y = (short) (CursorY(screen, screen->cur_row) + xw->work.xim_fs_ascent); 4948 list = XVaCreateNestedList(0, 4949 XNSpotLocation, &spot, 4950 XNForeground, T_COLOR(screen, TEXT_FG), 4951 XNBackground, T_COLOR(screen, TEXT_BG), 4952 (void *) 0); 4953 XSetICValues(input->xic, XNPreeditAttributes, list, (void *) 0); 4954 XFree(list); 4955 } 4956} 4957#endif 4958 4959static void 4960WrapLine(XtermWidget xw) 4961{ 4962 TScreen *screen = TScreenOf(xw); 4963 LineData *ld = getLineData(screen, screen->cur_row); 4964 4965 if (ld != 0) { 4966 /* mark that we had to wrap this line */ 4967 LineSetFlag(ld, LINEWRAPPED); 4968 if (screen->show_wrap_marks) { 4969 ShowWrapMarks(xw, screen->cur_row, ld); 4970 } 4971 xtermAutoPrint(xw, '\n'); 4972 xtermIndex(xw, 1); 4973 set_cur_col(screen, ScrnLeftMargin(xw)); 4974 } 4975} 4976 4977/* 4978 * process a string of characters according to the character set indicated 4979 * by charset. worry about end of line conditions (wraparound if selected). 4980 */ 4981void 4982dotext(XtermWidget xw, 4983 int charset, 4984 IChar *buf, /* start of characters to process */ 4985 Cardinal len) /* end */ 4986{ 4987 TScreen *screen = TScreenOf(xw); 4988#if OPT_WIDE_CHARS 4989 Cardinal chars_chomped = 1; 4990 int next_col = screen->cur_col; 4991#else 4992 int next_col, this_col; /* must be signed */ 4993#endif 4994 Cardinal offset; 4995 int right = ScrnRightMargin(xw); 4996 4997 /* 4998 * It is possible to use CUP, etc., to move outside margins. In that 4999 * case, the right-margin is ineffective. 5000 */ 5001 if (screen->cur_col > right) { 5002 right = screen->max_col; 5003 } 5004#if OPT_WIDE_CHARS 5005 if (screen->vt100_graphics) 5006#endif 5007 if (!xtermCharSetOut(xw, buf, buf + len, charset)) 5008 return; 5009 5010 if_OPT_XMC_GLITCH(screen, { 5011 Cardinal n; 5012 if (charset != '?') { 5013 for (n = 0; n < len; n++) { 5014 if (buf[n] == XMC_GLITCH) 5015 buf[n] = XMC_GLITCH + 1; 5016 } 5017 } 5018 }); 5019 5020#if OPT_WIDE_CHARS 5021 for (offset = 0; 5022 offset < len && (chars_chomped > 0 || screen->do_wrap); 5023 offset += chars_chomped) { 5024 int width_available = right + 1 - screen->cur_col; 5025 int width_here = 0; 5026 Boolean force_wrap; 5027 Boolean need_wrap; 5028 Boolean did_wrap; 5029 int last_chomp = 0; 5030 chars_chomped = 0; 5031 5032 do { 5033 force_wrap = False; 5034 need_wrap = False; 5035 did_wrap = False; 5036 5037 if (screen->do_wrap) { 5038 screen->do_wrap = False; 5039 if ((xw->flags & WRAPAROUND)) { 5040 WrapLine(xw); 5041 width_available = right + 1 - screen->cur_col; 5042 next_col = screen->cur_col; 5043 did_wrap = True; 5044 } 5045 } 5046 5047 /* 5048 * This can happen with left/right margins... 5049 */ 5050 if (width_available <= 0) { 5051 break; 5052 } 5053 5054 /* 5055 * Regarding the soft-hyphen aberration, see 5056 * http://archives.miloush.net/michkap/archive/2006/09/02/736881.html 5057 */ 5058 while (width_here <= width_available 5059 && chars_chomped < (len - offset)) { 5060 Cardinal n = chars_chomped + offset; 5061 if (!screen->utf8_mode 5062 || (screen->vt100_graphics && charset == '0')) { 5063 last_chomp = 1; 5064 } else if (screen->c1_printable && 5065 buf[n] >= 0x80 && 5066 buf[n] <= 0xa0) { 5067 last_chomp = 1; 5068 } else { 5069 last_chomp = my_wcwidth((wchar_t) buf[n]); 5070 if (last_chomp <= 0) { 5071 IChar ch = buf[n]; 5072 Bool eat_it = (ch > 127); 5073 if (ch == 0xad) { 5074 /* 5075 * Only display soft-hyphen if it happens to be at 5076 * the right-margin. While that means that only 5077 * the displayed character could be selected for 5078 * pasting, a well-behaved application would never 5079 * send this, anyway... 5080 */ 5081 if (width_here < width_available - 1) { 5082 eat_it = True; 5083 } else { 5084 last_chomp = 1; 5085 eat_it = False; 5086 } 5087 TRACE(("...will%s display soft-hyphen\n", 5088 eat_it ? " not" : "")); 5089 } 5090 /* 5091 * Supposedly we dealt with combining characters and 5092 * control characters in doparse(). Anything left over 5093 * is junk that we will not attempt to display. 5094 */ 5095 if (eat_it) { 5096 TRACE(("...will not display U+%04X\n", ch)); 5097 --len; 5098 while (n < len) { 5099 buf[n] = buf[n + 1]; 5100 ++n; 5101 } 5102 last_chomp = 0; 5103 chars_chomped--; 5104 } 5105 } 5106 } 5107 width_here += last_chomp; 5108 chars_chomped++; 5109 } 5110 5111 if (width_here > width_available) { 5112 if (last_chomp > right + 1) { 5113 break; /* give up - it is too big */ 5114 } else if (chars_chomped-- == 0) { 5115 /* This can happen with left/right margins... */ 5116 break; 5117 } 5118 width_here -= last_chomp; 5119 if (chars_chomped > 0) { 5120 if (!(xw->flags & WRAPAROUND)) { 5121 buf[chars_chomped + offset - 1] = buf[len - 1]; 5122 } else { 5123 need_wrap = True; 5124 } 5125 } 5126 } else if (width_here == width_available) { 5127 need_wrap = True; 5128 } else if (chars_chomped != (len - offset)) { 5129 need_wrap = True; 5130 } 5131 5132 if (chars_chomped != 0 && next_col <= screen->max_col) { 5133 WriteText(xw, buf + offset, chars_chomped); 5134 } else if (!did_wrap 5135 && len > 0 5136 && (xw->flags & WRAPAROUND) 5137 && screen->cur_col > ScrnLeftMargin(xw)) { 5138 force_wrap = True; 5139 need_wrap = True; 5140 } 5141 next_col += width_here; 5142 screen->do_wrap = need_wrap; 5143 } while (force_wrap); 5144 } 5145 5146 /* 5147 * Remember that we wrote something to the screen, for use as a base of 5148 * combining characters. The logic above may have called cursor-forward 5149 * or carriage-return operations which resets this flag, so we set it at 5150 * the very end. 5151 */ 5152 screen->char_was_written = True; 5153#else /* ! OPT_WIDE_CHARS */ 5154 5155 for (offset = 0; offset < len; offset += (Cardinal) this_col) { 5156#if OPT_DEC_CHRSET 5157 CLineData *ld = getLineData(screen, screen->cur_row); 5158#endif 5159 5160 int last_col = LineMaxCol(screen, ld); 5161 if (last_col > (right + 1)) 5162 last_col = right + 1; 5163 this_col = last_col - screen->cur_col + 1; 5164 if (this_col <= 1) { 5165 if (screen->do_wrap) { 5166 screen->do_wrap = False; 5167 if ((xw->flags & WRAPAROUND)) { 5168 WrapLine(xw); 5169 } 5170 } 5171 this_col = 1; 5172 } 5173 if (offset + (Cardinal) this_col > len) { 5174 this_col = (int) (len - offset); 5175 } 5176 next_col = screen->cur_col + this_col; 5177 5178 WriteText(xw, buf + offset, (unsigned) this_col); 5179 5180 /* 5181 * The call to WriteText updates screen->cur_col. 5182 * If screen->cur_col is less than next_col, we must have 5183 * hit the right margin - so set the do_wrap flag. 5184 */ 5185 screen->do_wrap = (Boolean) (screen->cur_col < next_col); 5186 } 5187 5188#endif /* OPT_WIDE_CHARS */ 5189} 5190 5191#if OPT_WIDE_CHARS 5192unsigned 5193visual_width(const IChar *str, Cardinal len) 5194{ 5195 /* returns the visual width of a string (doublewide characters count 5196 as 2, normalwide characters count as 1) */ 5197 unsigned my_len = 0; 5198 while (len) { 5199 int ch = (int) *str++; 5200 if (isWide(ch)) 5201 my_len += 2; 5202 else 5203 my_len++; 5204 len--; 5205 } 5206 return my_len; 5207} 5208#endif 5209 5210#if HANDLE_STRUCT_NOTIFY 5211/* Flag icon name with "***" on window output when iconified. 5212 */ 5213static void 5214HandleStructNotify(Widget w GCC_UNUSED, 5215 XtPointer closure GCC_UNUSED, 5216 XEvent *event, 5217 Boolean *cont GCC_UNUSED) 5218{ 5219 XtermWidget xw = term; 5220 5221 switch (event->type) { 5222 case MapNotify: 5223 TRACE(("HandleStructNotify(MapNotify) %#lx\n", event->xmap.window)); 5224 resetZIconBeep(xw); 5225 mapstate = !IsUnmapped; 5226 break; 5227 case UnmapNotify: 5228 TRACE(("HandleStructNotify(UnmapNotify) %#lx\n", event->xunmap.window)); 5229 mapstate = IsUnmapped; 5230 break; 5231 case ConfigureNotify: 5232 if (event->xconfigure.window == XtWindow(toplevel)) { 5233#if !OPT_TOOLBAR 5234 int height, width; 5235 5236 height = event->xconfigure.height; 5237 width = event->xconfigure.width; 5238#endif 5239 TRACE(("HandleStructNotify(ConfigureNotify) %#lx %d,%d %dx%d\n", 5240 event->xconfigure.window, 5241 event->xconfigure.y, event->xconfigure.x, 5242 event->xconfigure.height, event->xconfigure.width)); 5243 5244#if OPT_TOOLBAR 5245 /* 5246 * The notification is for the top-level widget, but we care about 5247 * vt100 (ignore the tek4014 window). 5248 */ 5249 if (TScreenOf(xw)->Vshow) { 5250 VTwin *Vwin = WhichVWin(TScreenOf(xw)); 5251 TbInfo *info = &(Vwin->tb_info); 5252 TbInfo save = *info; 5253 5254 if (info->menu_bar) { 5255 XtVaGetValues(info->menu_bar, 5256 XtNheight, &info->menu_height, 5257 XtNborderWidth, &info->menu_border, 5258 (XtPointer) 0); 5259 5260 if (save.menu_height != info->menu_height 5261 || save.menu_border != info->menu_border) { 5262 5263 TRACE(("...menu_height %d\n", info->menu_height)); 5264 TRACE(("...menu_border %d\n", info->menu_border)); 5265 TRACE(("...had height %d, border %d\n", 5266 save.menu_height, 5267 save.menu_border)); 5268 5269 /* 5270 * Window manager still may be using the old values. 5271 * Try to fool it. 5272 */ 5273 REQ_RESIZE((Widget) xw, 5274 TScreenOf(xw)->fullVwin.fullwidth, 5275 (Dimension) (info->menu_height 5276 - save.menu_height 5277 + TScreenOf(xw)->fullVwin.fullheight), 5278 NULL, NULL); 5279 repairSizeHints(); 5280 } 5281 } 5282 } 5283#else 5284 if (height != xw->hints.height || width != xw->hints.width) 5285 RequestResize(xw, height, width, False); 5286#endif /* OPT_TOOLBAR */ 5287 } 5288 break; 5289 case ReparentNotify: 5290 TRACE(("HandleStructNotify(ReparentNotify) %#lx\n", event->xreparent.window)); 5291 break; 5292 default: 5293 TRACE(("HandleStructNotify(event %s) %#lx\n", 5294 visibleEventType(event->type), 5295 event->xany.window)); 5296 break; 5297 } 5298} 5299#endif /* HANDLE_STRUCT_NOTIFY */ 5300 5301#if OPT_BLINK_CURS 5302static void 5303SetCursorBlink(TScreen *screen, Bool enable) 5304{ 5305 screen->cursor_blink = (Boolean) enable; 5306 if (DoStartBlinking(screen)) { 5307 StartBlinking(screen); 5308 } else { 5309 /* EMPTY */ 5310#if OPT_BLINK_TEXT 5311 reallyStopBlinking(screen); 5312#else 5313 StopBlinking(screen); 5314#endif 5315 } 5316 update_cursorblink(); 5317} 5318 5319void 5320ToggleCursorBlink(TScreen *screen) 5321{ 5322 SetCursorBlink(screen, (Bool) (!(screen->cursor_blink))); 5323} 5324#endif 5325 5326/* 5327 * process ANSI modes set, reset 5328 */ 5329static void 5330ansi_modes(XtermWidget xw, BitFunc func) 5331{ 5332 int i; 5333 5334 for (i = 0; i < nparam; ++i) { 5335 switch (GetParam(i)) { 5336 case 2: /* KAM (if set, keyboard locked */ 5337 (*func) (&xw->keyboard.flags, MODE_KAM); 5338 break; 5339 5340 case 4: /* IRM */ 5341 (*func) (&xw->flags, INSERT); 5342 break; 5343 5344 case 12: /* SRM (if set, local echo */ 5345 (*func) (&xw->keyboard.flags, MODE_SRM); 5346 break; 5347 5348 case 20: /* LNM */ 5349 (*func) (&xw->flags, LINEFEED); 5350 update_autolinefeed(); 5351 break; 5352 } 5353 } 5354} 5355 5356#define IsSM() (func == bitset) 5357 5358#define set_bool_mode(flag) \ 5359 flag = (Boolean) IsSM() 5360 5361static void 5362really_set_mousemode(XtermWidget xw, 5363 Bool enabled, 5364 XtermMouseModes mode) 5365{ 5366 TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF; 5367 if (okSendMousePos(xw) != MOUSE_OFF) 5368 xtermShowPointer(xw, True); 5369} 5370 5371#define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode) 5372 5373#if OPT_READLINE 5374#define set_mouseflag(f) \ 5375 (IsSM() \ 5376 ? SCREEN_FLAG_set(screen, f) \ 5377 : SCREEN_FLAG_unset(screen, f)) 5378#endif 5379 5380/* 5381 * process DEC private modes set, reset 5382 */ 5383static void 5384dpmodes(XtermWidget xw, BitFunc func) 5385{ 5386 TScreen *screen = TScreenOf(xw); 5387 int i, j; 5388 unsigned myflags; 5389 5390 TRACE(("changing %d DEC private modes\n", nparam)); 5391 for (i = 0; i < nparam; ++i) { 5392 int code = GetParam(i); 5393 5394 TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", code)); 5395 switch ((DECSET_codes) code) { 5396 case srm_DECCKM: 5397 (*func) (&xw->keyboard.flags, MODE_DECCKM); 5398 update_appcursor(); 5399 break; 5400 case srm_DECANM: /* ANSI/VT52 mode */ 5401 if (IsSM()) { /* ANSI (VT100) */ 5402 /* 5403 * Setting DECANM should have no effect, since this function 5404 * cannot be reached from vt52 mode. 5405 */ 5406 /* EMPTY */ ; 5407 } 5408#if OPT_VT52_MODE 5409 else if (screen->terminal_id >= 100) { /* VT52 */ 5410 TRACE(("DECANM terminal_id %d, vtXX_level %d\n", 5411 screen->terminal_id, 5412 screen->vtXX_level)); 5413 screen->vtXX_level = 0; 5414 screen->vt52_save_curgl = screen->curgl; 5415 screen->vt52_save_curgr = screen->curgr; 5416 screen->vt52_save_curss = screen->curss; 5417 memmove(screen->vt52_save_gsets, screen->gsets, sizeof(screen->gsets)); 5418 resetCharsets(screen); 5419 InitParams(); /* ignore the remaining params, if any */ 5420 } 5421#endif 5422 break; 5423 case srm_DECCOLM: 5424 if (screen->c132) { 5425 if (!(xw->flags & NOCLEAR_COLM)) 5426 ClearScreen(xw); 5427 CursorSet(screen, 0, 0, xw->flags); 5428 if ((j = IsSM()? 132 : 80) != 5429 ((xw->flags & IN132COLUMNS) ? 132 : 80) || 5430 j != MaxCols(screen)) 5431 RequestResize(xw, -1, j, True); 5432 (*func) (&xw->flags, IN132COLUMNS); 5433 if (xw->flags & IN132COLUMNS) { 5434 UIntClr(xw->flags, LEFT_RIGHT); 5435 reset_lr_margins(screen); 5436 } 5437 } 5438 break; 5439 case srm_DECSCLM: /* (slow scroll) */ 5440 if (IsSM()) { 5441 screen->jumpscroll = 0; 5442 if (screen->scroll_amt) 5443 FlushScroll(xw); 5444 } else 5445 screen->jumpscroll = 1; 5446 (*func) (&xw->flags, SMOOTHSCROLL); 5447 update_jumpscroll(); 5448 break; 5449 case srm_DECSCNM: 5450 myflags = xw->flags; 5451 (*func) (&xw->flags, REVERSE_VIDEO); 5452 if ((xw->flags ^ myflags) & REVERSE_VIDEO) 5453 ReverseVideo(xw); 5454 /* update_reversevideo done in RevVid */ 5455 break; 5456 5457 case srm_DECOM: 5458 (*func) (&xw->flags, ORIGIN); 5459 CursorSet(screen, 0, 0, xw->flags); 5460 break; 5461 5462 case srm_DECAWM: 5463 (*func) (&xw->flags, WRAPAROUND); 5464 update_autowrap(); 5465 break; 5466 case srm_DECARM: 5467 /* ignore autorepeat 5468 * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only 5469 * for the whole display - not limited to a given window. 5470 */ 5471 break; 5472 case srm_X10_MOUSE: /* MIT bogus sequence */ 5473 MotionOff(screen, xw); 5474 set_mousemode(X10_MOUSE); 5475 break; 5476#if OPT_TOOLBAR 5477 case srm_RXVT_TOOLBAR: 5478 ShowToolbar(IsSM()); 5479 break; 5480#endif 5481#if OPT_BLINK_CURS 5482 case srm_ATT610_BLINK: /* att610: Start/stop blinking cursor */ 5483 if (screen->cursor_blink_res) { 5484 set_bool_mode(screen->cursor_blink_esc); 5485 UpdateCursorBlink(screen); 5486 } 5487 break; 5488#endif 5489 case srm_DECPFF: /* print form feed */ 5490 set_bool_mode(PrinterOf(screen).printer_formfeed); 5491 break; 5492 case srm_DECPEX: /* print extent */ 5493 set_bool_mode(PrinterOf(screen).printer_extent); 5494 break; 5495 case srm_DECTCEM: /* Show/hide cursor (VT200) */ 5496 set_bool_mode(screen->cursor_set); 5497 break; 5498 case srm_RXVT_SCROLLBAR: 5499 if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF)) 5500 ToggleScrollBar(xw); 5501 break; 5502#if OPT_SHIFT_FONTS 5503 case srm_RXVT_FONTSIZE: 5504 set_bool_mode(xw->misc.shift_fonts); 5505 break; 5506#endif 5507#if OPT_TEK4014 5508 case srm_DECTEK: 5509 if (IsSM() && !(screen->inhibit & I_TEK)) { 5510 FlushLog(xw); 5511 TEK4014_ACTIVE(xw) = True; 5512 TRACE(("Tek4014 is now active...\n")); 5513 update_vttekmode(); 5514 } 5515 break; 5516#endif 5517 case srm_132COLS: /* 132 column mode */ 5518 set_bool_mode(screen->c132); 5519 update_allow132(); 5520 break; 5521 case srm_CURSES_HACK: 5522 set_bool_mode(screen->curses); 5523 update_cursesemul(); 5524 break; 5525 case srm_DECNRCM: /* national charset (VT220) */ 5526 if (screen->vtXX_level >= 2) { 5527 if ((*func) (&xw->flags, NATIONAL)) { 5528 modified_DECNRCM(xw); 5529 } 5530 } 5531 break; 5532 case srm_MARGIN_BELL: /* margin bell */ 5533 set_bool_mode(screen->marginbell); 5534 if (!screen->marginbell) 5535 screen->bellArmed = -1; 5536 update_marginbell(); 5537 break; 5538 case srm_REVERSEWRAP: /* reverse wraparound */ 5539 (*func) (&xw->flags, REVERSEWRAP); 5540 update_reversewrap(); 5541 break; 5542#ifdef ALLOWLOGGING 5543 case srm_ALLOWLOGGING: /* logging */ 5544#ifdef ALLOWLOGFILEONOFF 5545 /* 5546 * if this feature is enabled, logging may be 5547 * enabled and disabled via escape sequences. 5548 */ 5549 if (IsSM()) 5550 StartLog(xw); 5551 else 5552 CloseLog(xw); 5553#else 5554 Bell(xw, XkbBI_Info, 0); 5555 Bell(xw, XkbBI_Info, 0); 5556#endif /* ALLOWLOGFILEONOFF */ 5557 break; 5558#endif 5559 case srm_OPT_ALTBUF_CURSOR: /* alternate buffer & cursor */ 5560 if (!xw->misc.titeInhibit) { 5561 if (IsSM()) { 5562 CursorSave(xw); 5563 ToAlternate(xw, True); 5564 ClearScreen(xw); 5565 } else { 5566 FromAlternate(xw); 5567 CursorRestore(xw); 5568 } 5569 } else if (IsSM()) { 5570 do_ti_xtra_scroll(xw); 5571 } 5572 break; 5573 case srm_OPT_ALTBUF: 5574 /* FALLTHRU */ 5575 case srm_ALTBUF: /* alternate buffer */ 5576 if (!xw->misc.titeInhibit) { 5577 if (IsSM()) { 5578 ToAlternate(xw, False); 5579 } else { 5580 if (screen->whichBuf 5581 && (code == 1047)) 5582 ClearScreen(xw); 5583 FromAlternate(xw); 5584 } 5585 } else if (IsSM()) { 5586 do_ti_xtra_scroll(xw); 5587 } 5588 break; 5589 case srm_DECNKM: 5590 (*func) (&xw->keyboard.flags, MODE_DECKPAM); 5591 update_appkeypad(); 5592 break; 5593 case srm_DECBKM: 5594 /* back-arrow mapped to backspace or delete(D) */ 5595 (*func) (&xw->keyboard.flags, MODE_DECBKM); 5596 TRACE(("DECSET DECBKM %s\n", 5597 BtoS(xw->keyboard.flags & MODE_DECBKM))); 5598 update_decbkm(); 5599 break; 5600 case srm_DECLRMM: 5601 if (screen->vtXX_level >= 4) { /* VT420 */ 5602 (*func) (&xw->flags, LEFT_RIGHT); 5603 if (IsLeftRightMode(xw)) { 5604 xterm_ResetDouble(xw); 5605 } else { 5606 reset_lr_margins(screen); 5607 } 5608 } 5609 break; 5610#if OPT_SIXEL_GRAPHICS 5611 case srm_DECSDM: /* sixel scrolling */ 5612 if (screen->terminal_id == 240 || /* FIXME: VT24x did not scroll sixel graphics */ 5613 screen->terminal_id == 241 || 5614 screen->terminal_id == 330 || 5615 screen->terminal_id == 340 || 5616 screen->terminal_id == 382) { 5617 (*func) (&xw->keyboard.flags, MODE_DECSDM); 5618 TRACE(("DECSET/DECRST DECSDM %s (resource default is %d)\n", 5619 BtoS(xw->keyboard.flags & MODE_DECSDM), 5620 TScreenOf(xw)->sixel_scrolling)); 5621 update_decsdm(); 5622 } 5623 break; 5624#endif 5625 case srm_DECNCSM: 5626 if (screen->vtXX_level >= 5) { /* VT510 */ 5627 (*func) (&xw->flags, NOCLEAR_COLM); 5628 } 5629 break; 5630 case srm_VT200_MOUSE: /* xterm bogus sequence */ 5631 MotionOff(screen, xw); 5632 set_mousemode(VT200_MOUSE); 5633 break; 5634 case srm_VT200_HIGHLIGHT_MOUSE: /* xterm sequence w/hilite tracking */ 5635 MotionOff(screen, xw); 5636 set_mousemode(VT200_HIGHLIGHT_MOUSE); 5637 break; 5638 case srm_BTN_EVENT_MOUSE: 5639 MotionOff(screen, xw); 5640 set_mousemode(BTN_EVENT_MOUSE); 5641 break; 5642 case srm_ANY_EVENT_MOUSE: 5643 set_mousemode(ANY_EVENT_MOUSE); 5644 if (screen->send_mouse_pos == MOUSE_OFF) { 5645 MotionOff(screen, xw); 5646 } else { 5647 MotionOn(screen, xw); 5648 } 5649 break; 5650#if OPT_FOCUS_EVENT 5651 case srm_FOCUS_EVENT_MOUSE: 5652 set_bool_mode(screen->send_focus_pos); 5653 break; 5654#endif 5655 case srm_EXT_MODE_MOUSE: 5656 /* FALLTHRU */ 5657 case srm_SGR_EXT_MODE_MOUSE: 5658 /* FALLTHRU */ 5659 case srm_URXVT_EXT_MODE_MOUSE: 5660 /* 5661 * Rather than choose an arbitrary precedence among the coordinate 5662 * modes, they are mutually exclusive. For consistency, a reset is 5663 * only effective against the matching mode. 5664 */ 5665 if (IsSM()) { 5666 screen->extend_coords = code; 5667 } else if (screen->extend_coords == code) { 5668 screen->extend_coords = 0; 5669 } 5670 break; 5671 case srm_ALTERNATE_SCROLL: 5672 set_bool_mode(screen->alternateScroll); 5673 break; 5674 case srm_RXVT_SCROLL_TTY_OUTPUT: 5675 set_bool_mode(screen->scrollttyoutput); 5676 update_scrollttyoutput(); 5677 break; 5678 case srm_RXVT_SCROLL_TTY_KEYPRESS: 5679 set_bool_mode(screen->scrollkey); 5680 update_scrollkey(); 5681 break; 5682 case srm_EIGHT_BIT_META: 5683 if (screen->eight_bit_meta != ebNever) { 5684 set_bool_mode(screen->eight_bit_meta); 5685 } 5686 break; 5687#if OPT_NUM_LOCK 5688 case srm_REAL_NUMLOCK: 5689 set_bool_mode(xw->misc.real_NumLock); 5690 update_num_lock(); 5691 break; 5692 case srm_META_SENDS_ESC: 5693 set_bool_mode(screen->meta_sends_esc); 5694 update_meta_esc(); 5695 break; 5696#endif 5697 case srm_DELETE_IS_DEL: 5698 set_bool_mode(screen->delete_is_del); 5699 update_delete_del(); 5700 break; 5701#if OPT_NUM_LOCK 5702 case srm_ALT_SENDS_ESC: 5703 set_bool_mode(screen->alt_sends_esc); 5704 update_alt_esc(); 5705 break; 5706#endif 5707 case srm_KEEP_SELECTION: 5708 set_bool_mode(screen->keepSelection); 5709 update_keepSelection(); 5710 break; 5711 case srm_SELECT_TO_CLIPBOARD: 5712 set_bool_mode(screen->selectToClipboard); 5713 update_selectToClipboard(); 5714 break; 5715 case srm_BELL_IS_URGENT: 5716 set_bool_mode(screen->bellIsUrgent); 5717 update_bellIsUrgent(); 5718 break; 5719 case srm_POP_ON_BELL: 5720 set_bool_mode(screen->poponbell); 5721 update_poponbell(); 5722 break; 5723 case srm_KEEP_CLIPBOARD: 5724 set_bool_mode(screen->keepClipboard); 5725 update_keepClipboard(); 5726 break; 5727 case srm_TITE_INHIBIT: 5728 if (!xw->misc.titeInhibit) { 5729 if (IsSM()) 5730 CursorSave(xw); 5731 else 5732 CursorRestore(xw); 5733 } 5734 break; 5735#if OPT_TCAP_FKEYS 5736 case srm_TCAP_FKEYS: 5737 set_keyboard_type(xw, keyboardIsTermcap, IsSM()); 5738 break; 5739#endif 5740#if OPT_SUN_FUNC_KEYS 5741 case srm_SUN_FKEYS: 5742 set_keyboard_type(xw, keyboardIsSun, IsSM()); 5743 break; 5744#endif 5745#if OPT_HP_FUNC_KEYS 5746 case srm_HP_FKEYS: 5747 set_keyboard_type(xw, keyboardIsHP, IsSM()); 5748 break; 5749#endif 5750#if OPT_SCO_FUNC_KEYS 5751 case srm_SCO_FKEYS: 5752 set_keyboard_type(xw, keyboardIsSCO, IsSM()); 5753 break; 5754#endif 5755 case srm_LEGACY_FKEYS: 5756 set_keyboard_type(xw, keyboardIsLegacy, IsSM()); 5757 break; 5758#if OPT_SUNPC_KBD 5759 case srm_VT220_FKEYS: 5760 set_keyboard_type(xw, keyboardIsVT220, IsSM()); 5761 break; 5762#endif 5763#if OPT_READLINE 5764 case srm_BUTTON1_MOVE_POINT: 5765 set_mouseflag(click1_moves); 5766 break; 5767 case srm_BUTTON2_MOVE_POINT: 5768 set_mouseflag(paste_moves); 5769 break; 5770 case srm_DBUTTON3_DELETE: 5771 set_mouseflag(dclick3_deletes); 5772 break; 5773 case srm_PASTE_IN_BRACKET: 5774 set_mouseflag(paste_brackets); 5775 break; 5776 case srm_PASTE_QUOTE: 5777 set_mouseflag(paste_quotes); 5778 break; 5779 case srm_PASTE_LITERAL_NL: 5780 set_mouseflag(paste_literal_nl); 5781 break; 5782#endif /* OPT_READLINE */ 5783#if OPT_GRAPHICS 5784 case srm_PRIVATE_COLOR_REGISTERS: /* private color registers for each graphic */ 5785 TRACE(("DECSET/DECRST PRIVATE_COLOR_REGISTERS to %s (resource default is %s)\n", 5786 BtoS(screen->privatecolorregisters), 5787 BtoS(TScreenOf(xw)->privatecolorregisters))); 5788 set_bool_mode(screen->privatecolorregisters); 5789 update_privatecolorregisters(); 5790 break; 5791#endif 5792#if OPT_SIXEL_GRAPHICS 5793 case srm_SIXEL_SCROLLS_RIGHT: /* sixel scrolling moves cursor to right */ 5794 if (screen->terminal_id == 240 || /* FIXME: VT24x did not scroll sixel graphics */ 5795 screen->terminal_id == 241 || 5796 screen->terminal_id == 330 || 5797 screen->terminal_id == 340 || 5798 screen->terminal_id == 382) { 5799 set_bool_mode(screen->sixel_scrolls_right); 5800 TRACE(("DECSET/DECRST SIXEL_SCROLLS_RIGHT to %s (resource default is %s)\n", 5801 BtoS(screen->sixel_scrolls_right), 5802 BtoS(TScreenOf(xw)->sixel_scrolls_right))); 5803 } 5804 break; 5805#endif 5806 default: 5807 TRACE(("DATA_ERROR: unknown private code %d\n", code)); 5808 break; 5809 } 5810 } 5811} 5812 5813/* 5814 * process xterm private modes save 5815 */ 5816static void 5817savemodes(XtermWidget xw) 5818{ 5819 TScreen *screen = TScreenOf(xw); 5820 int i; 5821 5822 for (i = 0; i < nparam; i++) { 5823 int code = GetParam(i); 5824 5825 TRACE(("savemodes %d\n", code)); 5826 switch ((DECSET_codes) code) { 5827 case srm_DECCKM: 5828 DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM); 5829 break; 5830 case srm_DECANM: /* ANSI/VT52 mode */ 5831 /* no effect */ 5832 break; 5833 case srm_DECCOLM: 5834 if (screen->c132) 5835 DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS); 5836 break; 5837 case srm_DECSCLM: /* (slow scroll) */ 5838 DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL); 5839 break; 5840 case srm_DECSCNM: 5841 DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO); 5842 break; 5843 case srm_DECOM: 5844 DoSM(DP_DECOM, xw->flags & ORIGIN); 5845 break; 5846 case srm_DECAWM: 5847 DoSM(DP_DECAWM, xw->flags & WRAPAROUND); 5848 break; 5849 case srm_DECARM: 5850 /* ignore autorepeat */ 5851 break; 5852 case srm_X10_MOUSE: /* mouse bogus sequence */ 5853 DoSM(DP_X_X10MSE, screen->send_mouse_pos); 5854 break; 5855#if OPT_TOOLBAR 5856 case srm_RXVT_TOOLBAR: 5857 DoSM(DP_TOOLBAR, resource.toolBar); 5858 break; 5859#endif 5860#if OPT_BLINK_CURS 5861 case srm_ATT610_BLINK: /* att610: Start/stop blinking cursor */ 5862 if (screen->cursor_blink_res) { 5863 DoSM(DP_CRS_BLINK, screen->cursor_blink_esc); 5864 } 5865 break; 5866#endif 5867 case srm_DECPFF: /* print form feed */ 5868 DoSM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed); 5869 break; 5870 case srm_DECPEX: /* print extent */ 5871 DoSM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent); 5872 break; 5873 case srm_DECTCEM: /* Show/hide cursor (VT200) */ 5874 DoSM(DP_CRS_VISIBLE, screen->cursor_set); 5875 break; 5876 case srm_RXVT_SCROLLBAR: 5877 DoSM(DP_RXVT_SCROLLBAR, (screen->fullVwin.sb_info.width != 0)); 5878 break; 5879#if OPT_SHIFT_FONTS 5880 case srm_RXVT_FONTSIZE: 5881 DoSM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts); 5882 break; 5883#endif 5884#if OPT_TEK4014 5885 case srm_DECTEK: 5886 DoSM(DP_DECTEK, TEK4014_ACTIVE(xw)); 5887 break; 5888#endif 5889 case srm_132COLS: /* 132 column mode */ 5890 DoSM(DP_X_DECCOLM, screen->c132); 5891 break; 5892 case srm_CURSES_HACK: /* curses hack */ 5893 DoSM(DP_X_MORE, screen->curses); 5894 break; 5895 case srm_DECNRCM: /* national charset (VT220) */ 5896 if (screen->vtXX_level >= 2) { 5897 DoSM(DP_DECNRCM, xw->flags & NATIONAL); 5898 } 5899 break; 5900 case srm_MARGIN_BELL: /* margin bell */ 5901 DoSM(DP_X_MARGIN, screen->marginbell); 5902 break; 5903 case srm_REVERSEWRAP: /* reverse wraparound */ 5904 DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP); 5905 break; 5906#ifdef ALLOWLOGGING 5907 case srm_ALLOWLOGGING: /* logging */ 5908 DoSM(DP_X_LOGGING, screen->logging); 5909 break; 5910#endif 5911 case srm_OPT_ALTBUF_CURSOR: 5912 /* FALLTHRU */ 5913 case srm_OPT_ALTBUF: 5914 /* FALLTHRU */ 5915 case srm_ALTBUF: /* alternate buffer */ 5916 DoSM(DP_X_ALTSCRN, screen->whichBuf); 5917 break; 5918 case srm_DECNKM: 5919 DoSM(DP_DECKPAM, xw->keyboard.flags & MODE_DECKPAM); 5920 break; 5921 case srm_DECBKM: /* backarrow mapping */ 5922 DoSM(DP_DECBKM, xw->keyboard.flags & MODE_DECBKM); 5923 break; 5924 case srm_DECLRMM: /* left-right */ 5925 DoSM(DP_X_LRMM, LEFT_RIGHT); 5926 break; 5927#if OPT_SIXEL_GRAPHICS 5928 case srm_DECSDM: /* sixel scrolling */ 5929 DoSM(DP_DECSDM, xw->keyboard.flags & MODE_DECSDM); 5930 update_decsdm(); 5931 break; 5932#endif 5933 case srm_DECNCSM: /* noclear */ 5934 DoSM(DP_X_NCSM, NOCLEAR_COLM); 5935 break; 5936 case srm_VT200_MOUSE: /* mouse bogus sequence */ 5937 /* FALLTHRU */ 5938 case srm_VT200_HIGHLIGHT_MOUSE: 5939 /* FALLTHRU */ 5940 case srm_BTN_EVENT_MOUSE: 5941 /* FALLTHRU */ 5942 case srm_ANY_EVENT_MOUSE: 5943 DoSM(DP_X_MOUSE, screen->send_mouse_pos); 5944 break; 5945#if OPT_FOCUS_EVENT 5946 case srm_FOCUS_EVENT_MOUSE: 5947 DoSM(DP_X_FOCUS, screen->send_focus_pos); 5948 break; 5949#endif 5950 case srm_EXT_MODE_MOUSE: 5951 /* FALLTHRU */ 5952 case srm_SGR_EXT_MODE_MOUSE: 5953 /* FALLTHRU */ 5954 case srm_URXVT_EXT_MODE_MOUSE: 5955 DoSM(DP_X_EXT_MOUSE, screen->extend_coords); 5956 break; 5957 case srm_ALTERNATE_SCROLL: 5958 DoSM(DP_ALTERNATE_SCROLL, screen->alternateScroll); 5959 break; 5960 case srm_RXVT_SCROLL_TTY_OUTPUT: 5961 DoSM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput); 5962 break; 5963 case srm_RXVT_SCROLL_TTY_KEYPRESS: 5964 DoSM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey); 5965 break; 5966 case srm_EIGHT_BIT_META: 5967 DoSM(DP_EIGHT_BIT_META, screen->eight_bit_meta); 5968 break; 5969#if OPT_NUM_LOCK 5970 case srm_REAL_NUMLOCK: 5971 DoSM(DP_REAL_NUMLOCK, xw->misc.real_NumLock); 5972 break; 5973 case srm_META_SENDS_ESC: 5974 DoSM(DP_META_SENDS_ESC, screen->meta_sends_esc); 5975 break; 5976#endif 5977 case srm_DELETE_IS_DEL: 5978 DoSM(DP_DELETE_IS_DEL, screen->delete_is_del); 5979 break; 5980#if OPT_NUM_LOCK 5981 case srm_ALT_SENDS_ESC: 5982 DoSM(DP_ALT_SENDS_ESC, screen->alt_sends_esc); 5983 break; 5984#endif 5985 case srm_KEEP_SELECTION: 5986 DoSM(DP_KEEP_SELECTION, screen->keepSelection); 5987 break; 5988 case srm_SELECT_TO_CLIPBOARD: 5989 DoSM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard); 5990 break; 5991 case srm_BELL_IS_URGENT: 5992 DoSM(DP_BELL_IS_URGENT, screen->bellIsUrgent); 5993 break; 5994 case srm_POP_ON_BELL: 5995 DoSM(DP_POP_ON_BELL, screen->poponbell); 5996 break; 5997 case srm_KEEP_CLIPBOARD: 5998 DoSM(DP_KEEP_CLIPBOARD, screen->keepClipboard); 5999 break; 6000#if OPT_TCAP_FKEYS 6001 case srm_TCAP_FKEYS: 6002 /* FALLTHRU */ 6003#endif 6004#if OPT_SUN_FUNC_KEYS 6005 case srm_SUN_FKEYS: 6006 /* FALLTHRU */ 6007#endif 6008#if OPT_HP_FUNC_KEYS 6009 case srm_HP_FKEYS: 6010 /* FALLTHRU */ 6011#endif 6012#if OPT_SCO_FUNC_KEYS 6013 case srm_SCO_FKEYS: 6014 /* FALLTHRU */ 6015#endif 6016#if OPT_SUNPC_KBD 6017 case srm_VT220_FKEYS: 6018 /* FALLTHRU */ 6019#endif 6020 case srm_LEGACY_FKEYS: 6021 DoSM(DP_KEYBOARD_TYPE, xw->keyboard.type); 6022 break; 6023 case srm_TITE_INHIBIT: 6024 if (!xw->misc.titeInhibit) { 6025 CursorSave(xw); 6026 } 6027 break; 6028#if OPT_READLINE 6029 case srm_BUTTON1_MOVE_POINT: 6030 SCREEN_FLAG_save(screen, click1_moves); 6031 break; 6032 case srm_BUTTON2_MOVE_POINT: 6033 SCREEN_FLAG_save(screen, paste_moves); 6034 break; 6035 case srm_DBUTTON3_DELETE: 6036 SCREEN_FLAG_save(screen, dclick3_deletes); 6037 break; 6038 case srm_PASTE_IN_BRACKET: 6039 SCREEN_FLAG_save(screen, paste_brackets); 6040 break; 6041 case srm_PASTE_QUOTE: 6042 SCREEN_FLAG_save(screen, paste_quotes); 6043 break; 6044 case srm_PASTE_LITERAL_NL: 6045 SCREEN_FLAG_save(screen, paste_literal_nl); 6046 break; 6047#endif /* OPT_READLINE */ 6048#if OPT_GRAPHICS 6049 case srm_PRIVATE_COLOR_REGISTERS: /* private color registers for each graphic */ 6050 TRACE(("save PRIVATE_COLOR_REGISTERS %s\n", 6051 BtoS(screen->privatecolorregisters))); 6052 DoSM(DP_X_PRIVATE_COLOR_REGISTERS, screen->privatecolorregisters); 6053 update_privatecolorregisters(); 6054 break; 6055#endif 6056#if OPT_SIXEL_GRAPHICS 6057 case srm_SIXEL_SCROLLS_RIGHT: 6058 TRACE(("save SIXEL_SCROLLS_RIGHT %s\n", 6059 BtoS(screen->sixel_scrolls_right))); 6060 DoSM(DP_SIXEL_SCROLLS_RIGHT, screen->sixel_scrolls_right); 6061 break; 6062#endif 6063 } 6064 } 6065} 6066 6067/* 6068 * process xterm private modes restore 6069 */ 6070static void 6071restoremodes(XtermWidget xw) 6072{ 6073 TScreen *screen = TScreenOf(xw); 6074 int i, j; 6075 6076 for (i = 0; i < nparam; i++) { 6077 int code = GetParam(i); 6078 6079 TRACE(("restoremodes %d\n", code)); 6080 switch ((DECSET_codes) code) { 6081 case srm_DECCKM: 6082 bitcpy(&xw->keyboard.flags, 6083 screen->save_modes[DP_DECCKM], MODE_DECCKM); 6084 update_appcursor(); 6085 break; 6086 case srm_DECANM: /* ANSI/VT52 mode */ 6087 /* no effect */ 6088 break; 6089 case srm_DECCOLM: 6090 if (screen->c132) { 6091 if (!(xw->flags & NOCLEAR_COLM)) 6092 ClearScreen(xw); 6093 CursorSet(screen, 0, 0, xw->flags); 6094 if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS) 6095 ? 132 : 80) != ((xw->flags & IN132COLUMNS) 6096 ? 132 : 80) || j != MaxCols(screen)) 6097 RequestResize(xw, -1, j, True); 6098 bitcpy(&xw->flags, 6099 screen->save_modes[DP_DECCOLM], 6100 IN132COLUMNS); 6101 } 6102 break; 6103 case srm_DECSCLM: /* (slow scroll) */ 6104 if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) { 6105 screen->jumpscroll = 0; 6106 if (screen->scroll_amt) 6107 FlushScroll(xw); 6108 } else 6109 screen->jumpscroll = 1; 6110 bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL); 6111 update_jumpscroll(); 6112 break; 6113 case srm_DECSCNM: 6114 if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) { 6115 bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO); 6116 ReverseVideo(xw); 6117 /* update_reversevideo done in RevVid */ 6118 } 6119 break; 6120 case srm_DECOM: 6121 bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN); 6122 CursorSet(screen, 0, 0, xw->flags); 6123 break; 6124 6125 case srm_DECAWM: 6126 bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND); 6127 update_autowrap(); 6128 break; 6129 case srm_DECARM: 6130 /* ignore autorepeat */ 6131 break; 6132 case srm_X10_MOUSE: /* MIT bogus sequence */ 6133 DoRM0(DP_X_X10MSE, screen->send_mouse_pos); 6134 really_set_mousemode(xw, 6135 screen->send_mouse_pos != MOUSE_OFF, 6136 (XtermMouseModes) screen->send_mouse_pos); 6137 break; 6138#if OPT_TOOLBAR 6139 case srm_RXVT_TOOLBAR: 6140 DoRM(DP_TOOLBAR, resource.toolBar); 6141 ShowToolbar(resource.toolBar); 6142 break; 6143#endif 6144#if OPT_BLINK_CURS 6145 case srm_ATT610_BLINK: /* Start/stop blinking cursor */ 6146 if (screen->cursor_blink_res) { 6147 DoRM(DP_CRS_BLINK, screen->cursor_blink_esc); 6148 UpdateCursorBlink(screen); 6149 } 6150 break; 6151#endif 6152 case srm_DECPFF: /* print form feed */ 6153 DoRM(DP_PRN_FORMFEED, PrinterOf(screen).printer_formfeed); 6154 break; 6155 case srm_DECPEX: /* print extent */ 6156 DoRM(DP_PRN_EXTENT, PrinterOf(screen).printer_extent); 6157 break; 6158 case srm_DECTCEM: /* Show/hide cursor (VT200) */ 6159 DoRM(DP_CRS_VISIBLE, screen->cursor_set); 6160 break; 6161 case srm_RXVT_SCROLLBAR: 6162 if ((screen->fullVwin.sb_info.width != 0) != 6163 screen->save_modes[DP_RXVT_SCROLLBAR]) { 6164 ToggleScrollBar(xw); 6165 } 6166 break; 6167#if OPT_SHIFT_FONTS 6168 case srm_RXVT_FONTSIZE: 6169 DoRM(DP_RXVT_FONTSIZE, xw->misc.shift_fonts); 6170 break; 6171#endif 6172#if OPT_TEK4014 6173 case srm_DECTEK: 6174 if (!(screen->inhibit & I_TEK) && 6175 (TEK4014_ACTIVE(xw) != (Boolean) screen->save_modes[DP_DECTEK])) { 6176 FlushLog(xw); 6177 TEK4014_ACTIVE(xw) = (Boolean) screen->save_modes[DP_DECTEK]; 6178 update_vttekmode(); 6179 } 6180 break; 6181#endif 6182 case srm_132COLS: /* 132 column mode */ 6183 DoRM(DP_X_DECCOLM, screen->c132); 6184 update_allow132(); 6185 break; 6186 case srm_CURSES_HACK: /* curses hack */ 6187 DoRM(DP_X_MORE, screen->curses); 6188 update_cursesemul(); 6189 break; 6190 case srm_DECNRCM: /* national charset (VT220) */ 6191 if (screen->vtXX_level >= 2) { 6192 if (bitcpy(&xw->flags, screen->save_modes[DP_DECNRCM], NATIONAL)) 6193 modified_DECNRCM(xw); 6194 } 6195 break; 6196 case srm_MARGIN_BELL: /* margin bell */ 6197 if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0) 6198 screen->bellArmed = -1; 6199 update_marginbell(); 6200 break; 6201 case srm_REVERSEWRAP: /* reverse wraparound */ 6202 bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP); 6203 update_reversewrap(); 6204 break; 6205#ifdef ALLOWLOGGING 6206 case srm_ALLOWLOGGING: /* logging */ 6207#ifdef ALLOWLOGFILEONOFF 6208 if (screen->save_modes[DP_X_LOGGING]) 6209 StartLog(xw); 6210 else 6211 CloseLog(xw); 6212#endif /* ALLOWLOGFILEONOFF */ 6213 /* update_logging done by StartLog and CloseLog */ 6214 break; 6215#endif 6216 case srm_OPT_ALTBUF_CURSOR: /* alternate buffer & cursor */ 6217 /* FALLTHRU */ 6218 case srm_OPT_ALTBUF: 6219 /* FALLTHRU */ 6220 case srm_ALTBUF: /* alternate buffer */ 6221 if (!xw->misc.titeInhibit) { 6222 if (screen->save_modes[DP_X_ALTSCRN]) 6223 ToAlternate(xw, False); 6224 else 6225 FromAlternate(xw); 6226 /* update_altscreen done by ToAlt and FromAlt */ 6227 } else if (screen->save_modes[DP_X_ALTSCRN]) { 6228 do_ti_xtra_scroll(xw); 6229 } 6230 break; 6231 case srm_DECNKM: 6232 bitcpy(&xw->flags, screen->save_modes[DP_DECKPAM], MODE_DECKPAM); 6233 update_appkeypad(); 6234 break; 6235 case srm_DECBKM: /* backarrow mapping */ 6236 bitcpy(&xw->flags, screen->save_modes[DP_DECBKM], MODE_DECBKM); 6237 update_decbkm(); 6238 break; 6239 case srm_DECLRMM: /* left-right */ 6240 bitcpy(&xw->flags, screen->save_modes[DP_X_LRMM], LEFT_RIGHT); 6241 if (IsLeftRightMode(xw)) { 6242 xterm_ResetDouble(xw); 6243 } else { 6244 reset_lr_margins(screen); 6245 } 6246 break; 6247#if OPT_SIXEL_GRAPHICS 6248 case srm_DECSDM: /* sixel scrolling */ 6249 bitcpy(&xw->keyboard.flags, screen->save_modes[DP_DECSDM], MODE_DECSDM); 6250 update_decsdm(); 6251 break; 6252#endif 6253 case srm_DECNCSM: /* noclear */ 6254 bitcpy(&xw->flags, screen->save_modes[DP_X_NCSM], NOCLEAR_COLM); 6255 break; 6256 case srm_VT200_MOUSE: /* mouse bogus sequence */ 6257 /* FALLTHRU */ 6258 case srm_VT200_HIGHLIGHT_MOUSE: 6259 /* FALLTHRU */ 6260 case srm_BTN_EVENT_MOUSE: 6261 /* FALLTHRU */ 6262 case srm_ANY_EVENT_MOUSE: 6263 DoRM0(DP_X_MOUSE, screen->send_mouse_pos); 6264 really_set_mousemode(xw, 6265 screen->send_mouse_pos != MOUSE_OFF, 6266 (XtermMouseModes) screen->send_mouse_pos); 6267 break; 6268#if OPT_FOCUS_EVENT 6269 case srm_FOCUS_EVENT_MOUSE: 6270 DoRM(DP_X_FOCUS, screen->send_focus_pos); 6271 break; 6272#endif 6273 case srm_EXT_MODE_MOUSE: 6274 /* FALLTHRU */ 6275 case srm_SGR_EXT_MODE_MOUSE: 6276 /* FALLTHRU */ 6277 case srm_URXVT_EXT_MODE_MOUSE: 6278 DoRM(DP_X_EXT_MOUSE, screen->extend_coords); 6279 break; 6280 case srm_TITE_INHIBIT: 6281 if (!xw->misc.titeInhibit) { 6282 CursorRestore(xw); 6283 } 6284 break; 6285 case srm_ALTERNATE_SCROLL: 6286 DoRM(DP_ALTERNATE_SCROLL, screen->alternateScroll); 6287 break; 6288 case srm_RXVT_SCROLL_TTY_OUTPUT: 6289 DoRM(DP_RXVT_SCROLL_TTY_OUTPUT, screen->scrollttyoutput); 6290 update_scrollttyoutput(); 6291 break; 6292 case srm_RXVT_SCROLL_TTY_KEYPRESS: 6293 DoRM(DP_RXVT_SCROLL_TTY_KEYPRESS, screen->scrollkey); 6294 update_scrollkey(); 6295 break; 6296 case srm_EIGHT_BIT_META: 6297 DoRM(DP_EIGHT_BIT_META, screen->eight_bit_meta); 6298 break; 6299#if OPT_NUM_LOCK 6300 case srm_REAL_NUMLOCK: 6301 DoRM(DP_REAL_NUMLOCK, xw->misc.real_NumLock); 6302 update_num_lock(); 6303 break; 6304 case srm_META_SENDS_ESC: 6305 DoRM(DP_META_SENDS_ESC, screen->meta_sends_esc); 6306 update_meta_esc(); 6307 break; 6308#endif 6309 case srm_DELETE_IS_DEL: 6310 DoRM(DP_DELETE_IS_DEL, screen->delete_is_del); 6311 update_delete_del(); 6312 break; 6313#if OPT_NUM_LOCK 6314 case srm_ALT_SENDS_ESC: 6315 DoRM(DP_ALT_SENDS_ESC, screen->alt_sends_esc); 6316 update_alt_esc(); 6317 break; 6318#endif 6319 case srm_KEEP_SELECTION: 6320 DoRM(DP_KEEP_SELECTION, screen->keepSelection); 6321 update_keepSelection(); 6322 break; 6323 case srm_SELECT_TO_CLIPBOARD: 6324 DoRM(DP_SELECT_TO_CLIPBOARD, screen->selectToClipboard); 6325 update_selectToClipboard(); 6326 break; 6327 case srm_BELL_IS_URGENT: 6328 DoRM(DP_BELL_IS_URGENT, screen->bellIsUrgent); 6329 update_bellIsUrgent(); 6330 break; 6331 case srm_POP_ON_BELL: 6332 DoRM(DP_POP_ON_BELL, screen->poponbell); 6333 update_poponbell(); 6334 break; 6335 case srm_KEEP_CLIPBOARD: 6336 DoRM(DP_KEEP_CLIPBOARD, screen->keepClipboard); 6337 update_keepClipboard(); 6338 break; 6339#if OPT_TCAP_FKEYS 6340 case srm_TCAP_FKEYS: 6341 /* FALLTHRU */ 6342#endif 6343#if OPT_SUN_FUNC_KEYS 6344 case srm_SUN_FKEYS: 6345 /* FALLTHRU */ 6346#endif 6347#if OPT_HP_FUNC_KEYS 6348 case srm_HP_FKEYS: 6349 /* FALLTHRU */ 6350#endif 6351#if OPT_SCO_FUNC_KEYS 6352 case srm_SCO_FKEYS: 6353 /* FALLTHRU */ 6354#endif 6355#if OPT_SUNPC_KBD 6356 case srm_VT220_FKEYS: 6357 /* FALLTHRU */ 6358#endif 6359 case srm_LEGACY_FKEYS: 6360 xw->keyboard.type = (xtermKeyboardType) screen->save_modes[DP_KEYBOARD_TYPE]; 6361 break; 6362#if OPT_READLINE 6363 case srm_BUTTON1_MOVE_POINT: 6364 SCREEN_FLAG_restore(screen, click1_moves); 6365 break; 6366 case srm_BUTTON2_MOVE_POINT: 6367 SCREEN_FLAG_restore(screen, paste_moves); 6368 break; 6369 case srm_DBUTTON3_DELETE: 6370 SCREEN_FLAG_restore(screen, dclick3_deletes); 6371 break; 6372 case srm_PASTE_IN_BRACKET: 6373 SCREEN_FLAG_restore(screen, paste_brackets); 6374 break; 6375 case srm_PASTE_QUOTE: 6376 SCREEN_FLAG_restore(screen, paste_quotes); 6377 break; 6378 case srm_PASTE_LITERAL_NL: 6379 SCREEN_FLAG_restore(screen, paste_literal_nl); 6380 break; 6381#endif /* OPT_READLINE */ 6382#if OPT_GRAPHICS 6383 case srm_PRIVATE_COLOR_REGISTERS: /* private color registers for each graphic */ 6384 TRACE(("restore PRIVATE_COLOR_REGISTERS before: %s\n", 6385 BtoS(screen->privatecolorregisters))); 6386 DoRM(DP_X_PRIVATE_COLOR_REGISTERS, screen->privatecolorregisters); 6387 TRACE(("restore PRIVATE_COLOR_REGISTERS after: %s\n", 6388 BtoS(screen->privatecolorregisters))); 6389 update_privatecolorregisters(); 6390 break; 6391#endif 6392#if OPT_SIXEL_GRAPHICS 6393 case srm_SIXEL_SCROLLS_RIGHT: 6394 TRACE(("restore SIXEL_SCROLLS_RIGHT before: %s\n", 6395 BtoS(screen->sixel_scrolls_right))); 6396 DoRM(DP_SIXEL_SCROLLS_RIGHT, screen->sixel_scrolls_right); 6397 TRACE(("restore SIXEL_SCROLLS_RIGHT after: %s\n", 6398 BtoS(screen->sixel_scrolls_right))); 6399 break; 6400#endif 6401 } 6402 } 6403} 6404 6405/* 6406 * Convert an XTextProperty to a string. 6407 * 6408 * This frees the data owned by the XTextProperty, and returns in its place the 6409 * string, which must be freed by the caller. 6410 */ 6411static char * 6412property_to_string(XtermWidget xw, XTextProperty * text) 6413{ 6414 TScreen *screen = TScreenOf(xw); 6415 Display *dpy = screen->display; 6416 char *result = 0; 6417 char **list; 6418 int length = 0; 6419 int rc; 6420 6421 TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n", 6422 text->value, 6423 TraceAtomName(dpy, text->encoding), 6424 text->format, 6425 text->nitems)); 6426 6427#if OPT_WIDE_CHARS 6428 /* 6429 * We will use the XmbTextPropertyToTextList call to extract UTF-8 data. 6430 * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to 6431 * ISO-8859-1. 6432 */ 6433 if ((text->format != 8) 6434 || IsTitleMode(xw, tmGetUtf8) 6435 || (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0) 6436#endif 6437 if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0) 6438 rc = XTextPropertyToStringList(text, &list, &length); 6439 6440 if (rc >= 0) { 6441 int n, c, pass; 6442 size_t need = 0; 6443 6444 for (pass = 0; pass < 2; ++pass) { 6445 for (n = 0, need = 0; n < length; n++) { 6446 char *s = list[n]; 6447 while ((c = *s++) != '\0') { 6448 if (pass) 6449 result[need] = (char) c; 6450 ++need; 6451 } 6452 } 6453 if (pass) 6454 result[need] = '\0'; 6455 else 6456 result = malloc(need + 1); 6457 if (result == 0) 6458 break; 6459 } 6460 XFreeStringList(list); 6461 } 6462 if (text->value != 0) 6463 XFree(text->value); 6464 6465 return result; 6466} 6467 6468static char * 6469get_icon_label(XtermWidget xw) 6470{ 6471 XTextProperty text; 6472 char *result = 0; 6473 6474 if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow(xw), &text)) { 6475 result = property_to_string(xw, &text); 6476 } 6477 return result; 6478} 6479 6480static char * 6481get_window_label(XtermWidget xw) 6482{ 6483 XTextProperty text; 6484 char *result = 0; 6485 6486 if (XGetWMName(TScreenOf(xw)->display, VShellWindow(xw), &text)) { 6487 result = property_to_string(xw, &text); 6488 } 6489 return result; 6490} 6491 6492/* 6493 * Report window label (icon or title) in dtterm protocol 6494 * ESC ] code label ESC backslash 6495 */ 6496static void 6497report_win_label(XtermWidget xw, 6498 int code, 6499 char *text) 6500{ 6501 unparseputc(xw, ANSI_ESC); 6502 unparseputc(xw, ']'); 6503 unparseputc(xw, code); 6504 6505 if (text != 0) { 6506 int copy = IsTitleMode(xw, tmGetBase16); 6507 if (copy) { 6508 TRACE(("Encoding hex:%s\n", text)); 6509 text = x_encode_hex(text); 6510 } 6511 unparseputs(xw, text); 6512 if (copy) 6513 free(text); 6514 } 6515 6516 unparseputc(xw, ANSI_ESC); 6517 unparseputc(xw, '\\'); /* should be ST */ 6518 unparse_end(xw); 6519} 6520 6521/* 6522 * Window operations (from CDE dtterm description, as well as extensions). 6523 * See also "allowWindowOps" resource. 6524 */ 6525static void 6526window_ops(XtermWidget xw) 6527{ 6528 TScreen *screen = TScreenOf(xw); 6529 XWindowChanges values; 6530 XWindowAttributes win_attrs; 6531#if OPT_MAXIMIZE 6532 unsigned root_width; 6533 unsigned root_height; 6534#endif 6535 int code = zero_if_default(0); 6536 char *label; 6537 6538 TRACE(("window_ops %d\n", code)); 6539 switch (code) { 6540 case ewRestoreWin: /* Restore (de-iconify) window */ 6541 if (AllowWindowOps(xw, ewRestoreWin)) { 6542 TRACE(("...de-iconify window\n")); 6543 XMapWindow(screen->display, 6544 VShellWindow(xw)); 6545 } 6546 break; 6547 6548 case ewMinimizeWin: /* Minimize (iconify) window */ 6549 if (AllowWindowOps(xw, ewMinimizeWin)) { 6550 TRACE(("...iconify window\n")); 6551 XIconifyWindow(screen->display, 6552 VShellWindow(xw), 6553 DefaultScreen(screen->display)); 6554 } 6555 break; 6556 6557 case ewSetWinPosition: /* Move the window to the given position */ 6558 if (AllowWindowOps(xw, ewSetWinPosition)) { 6559 unsigned value_mask; 6560 6561 values.x = zero_if_default(1); 6562 values.y = zero_if_default(2); 6563 TRACE(("...move window to %d,%d\n", values.x, values.y)); 6564 value_mask = (CWX | CWY); 6565 XReconfigureWMWindow(screen->display, 6566 VShellWindow(xw), 6567 DefaultScreen(screen->display), 6568 value_mask, 6569 &values); 6570 } 6571 break; 6572 6573 case ewSetWinSizePixels: /* Resize the window to given size in pixels */ 6574 if (AllowWindowOps(xw, ewSetWinSizePixels)) { 6575 RequestResize(xw, optional_param(1), optional_param(2), False); 6576 } 6577 break; 6578 6579 case ewRaiseWin: /* Raise the window to the front of the stack */ 6580 if (AllowWindowOps(xw, ewRaiseWin)) { 6581 TRACE(("...raise window\n")); 6582 XRaiseWindow(screen->display, VShellWindow(xw)); 6583 } 6584 break; 6585 6586 case ewLowerWin: /* Lower the window to the bottom of the stack */ 6587 if (AllowWindowOps(xw, ewLowerWin)) { 6588 TRACE(("...lower window\n")); 6589 XLowerWindow(screen->display, VShellWindow(xw)); 6590 } 6591 break; 6592 6593 case ewRefreshWin: /* Refresh the window */ 6594 if (AllowWindowOps(xw, ewRefreshWin)) { 6595 TRACE(("...redraw window\n")); 6596 Redraw(); 6597 } 6598 break; 6599 6600 case ewSetWinSizeChars: /* Resize the text-area, in characters */ 6601 if (AllowWindowOps(xw, ewSetWinSizeChars)) { 6602 RequestResize(xw, optional_param(1), optional_param(2), True); 6603 } 6604 break; 6605 6606#if OPT_MAXIMIZE 6607 case ewMaximizeWin: /* Maximize or restore */ 6608 if (AllowWindowOps(xw, ewMaximizeWin)) { 6609 RequestMaximize(xw, zero_if_default(1)); 6610 } 6611 break; 6612 case ewFullscreenWin: /* Fullscreen or restore */ 6613 if (AllowWindowOps(xw, ewFullscreenWin)) { 6614 FullScreen(xw, zero_if_default(1)); 6615 } 6616 break; 6617#endif 6618 6619 case ewGetWinState: /* Report the window's state */ 6620 if (AllowWindowOps(xw, ewGetWinState)) { 6621 TRACE(("...get window attributes\n")); 6622 xtermGetWinAttrs(screen->display, 6623 VWindow(screen), 6624 &win_attrs); 6625 init_reply(ANSI_CSI); 6626 reply.a_pintro = 0; 6627 reply.a_nparam = 1; 6628 reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable) 6629 ? 1 6630 : 2); 6631 reply.a_inters = 0; 6632 reply.a_final = 't'; 6633 unparseseq(xw, &reply); 6634 } 6635 break; 6636 6637 case ewGetWinPosition: /* Report the window's position */ 6638 if (AllowWindowOps(xw, ewGetWinPosition)) { 6639 TRACE(("...get window position\n")); 6640 xtermGetWinAttrs(screen->display, 6641 WMFrameWindow(xw), 6642 &win_attrs); 6643 init_reply(ANSI_CSI); 6644 reply.a_pintro = 0; 6645 reply.a_nparam = 3; 6646 reply.a_param[0] = 3; 6647 reply.a_param[1] = (ParmType) win_attrs.x; 6648 reply.a_param[2] = (ParmType) win_attrs.y; 6649 reply.a_inters = 0; 6650 reply.a_final = 't'; 6651 unparseseq(xw, &reply); 6652 } 6653 break; 6654 6655 case ewGetWinSizePixels: /* Report the window's size in pixels */ 6656 if (AllowWindowOps(xw, ewGetWinSizePixels)) { 6657 TRACE(("...get window size in pixels\n")); 6658 init_reply(ANSI_CSI); 6659 reply.a_pintro = 0; 6660 reply.a_nparam = 3; 6661 reply.a_param[0] = 4; 6662 reply.a_param[1] = (ParmType) Height(screen); 6663 reply.a_param[2] = (ParmType) Width(screen); 6664 reply.a_inters = 0; 6665 reply.a_final = 't'; 6666 unparseseq(xw, &reply); 6667 } 6668 break; 6669 6670 case ewGetWinSizeChars: /* Report the text's size in characters */ 6671 if (AllowWindowOps(xw, ewGetWinSizeChars)) { 6672 TRACE(("...get window size in characters\n")); 6673 init_reply(ANSI_CSI); 6674 reply.a_pintro = 0; 6675 reply.a_nparam = 3; 6676 reply.a_param[0] = 8; 6677 reply.a_param[1] = (ParmType) MaxRows(screen); 6678 reply.a_param[2] = (ParmType) MaxCols(screen); 6679 reply.a_inters = 0; 6680 reply.a_final = 't'; 6681 unparseseq(xw, &reply); 6682 } 6683 break; 6684 6685#if OPT_MAXIMIZE 6686 case ewGetScreenSizeChars: /* Report the screen's size, in characters */ 6687 if (AllowWindowOps(xw, ewGetScreenSizeChars)) { 6688 TRACE(("...get screen size in characters\n")); 6689 TRACE(("...using font size %dx%d\n", 6690 FontHeight(screen), 6691 FontWidth(screen))); 6692 (void) QueryMaximize(xw, &root_width, &root_height); 6693 init_reply(ANSI_CSI); 6694 reply.a_pintro = 0; 6695 reply.a_nparam = 3; 6696 reply.a_param[0] = 9; 6697 reply.a_param[1] = (ParmType) (root_height 6698 / (unsigned) FontHeight(screen)); 6699 reply.a_param[2] = (ParmType) (root_width 6700 / (unsigned) FontWidth(screen)); 6701 reply.a_inters = 0; 6702 reply.a_final = 't'; 6703 unparseseq(xw, &reply); 6704 } 6705 break; 6706#endif 6707 6708 case ewGetIconTitle: /* Report the icon's label */ 6709 if (AllowWindowOps(xw, ewGetIconTitle)) { 6710 TRACE(("...get icon's label\n")); 6711 report_win_label(xw, 'L', label = get_icon_label(xw)); 6712 free(label); 6713 } 6714 break; 6715 6716 case ewGetWinTitle: /* Report the window's title */ 6717 if (AllowWindowOps(xw, ewGetWinTitle)) { 6718 TRACE(("...get window's label\n")); 6719 report_win_label(xw, 'l', label = get_window_label(xw)); 6720 free(label); 6721 } 6722 break; 6723 6724 case ewPushTitle: /* save the window's title(s) on stack */ 6725 if (AllowWindowOps(xw, ewPushTitle)) { 6726 SaveTitle *last = screen->save_title; 6727 SaveTitle *item = TypeCalloc(SaveTitle); 6728 6729 TRACE(("...push title onto stack\n")); 6730 if (item != 0) { 6731 switch (zero_if_default(1)) { 6732 case 0: 6733 item->iconName = get_icon_label(xw); 6734 item->windowName = get_window_label(xw); 6735 break; 6736 case 1: 6737 item->iconName = get_icon_label(xw); 6738 break; 6739 case 2: 6740 item->windowName = get_window_label(xw); 6741 break; 6742 } 6743 item->next = last; 6744 if (item->iconName == 0) { 6745 item->iconName = ((last == 0) 6746 ? get_icon_label(xw) 6747 : x_strdup(last->iconName)); 6748 } 6749 if (item->windowName == 0) { 6750 item->windowName = ((last == 0) 6751 ? get_window_label(xw) 6752 : x_strdup(last->windowName)); 6753 } 6754 screen->save_title = item; 6755 } 6756 } 6757 break; 6758 6759 case ewPopTitle: /* restore the window's title(s) from stack */ 6760 if (AllowWindowOps(xw, ewPopTitle)) { 6761 SaveTitle *item = screen->save_title; 6762 6763 TRACE(("...pop title off stack\n")); 6764 if (item != 0) { 6765 switch (zero_if_default(1)) { 6766 case 0: 6767 ChangeIconName(xw, item->iconName); 6768 ChangeTitle(xw, item->windowName); 6769 break; 6770 case 1: 6771 ChangeIconName(xw, item->iconName); 6772 break; 6773 case 2: 6774 ChangeTitle(xw, item->windowName); 6775 break; 6776 } 6777 screen->save_title = item->next; 6778 free(item->iconName); 6779 free(item->windowName); 6780 free(item); 6781 } 6782 } 6783 break; 6784 6785 default: /* DECSLPP (24, 25, 36, 48, 72, 144) */ 6786 if (AllowWindowOps(xw, ewSetWinLines)) { 6787 if (code >= 24) 6788 RequestResize(xw, code, -1, True); 6789 } 6790 break; 6791 } 6792} 6793 6794/* 6795 * set a bit in a word given a pointer to the word and a mask. 6796 */ 6797static int 6798bitset(unsigned *p, unsigned mask) 6799{ 6800 unsigned before = *p; 6801 *p |= mask; 6802 return (before != *p); 6803} 6804 6805/* 6806 * clear a bit in a word given a pointer to the word and a mask. 6807 */ 6808static int 6809bitclr(unsigned *p, unsigned mask) 6810{ 6811 unsigned before = *p; 6812 *p &= ~mask; 6813 return (before != *p); 6814} 6815 6816/* 6817 * Copy bits from one word to another, given a mask 6818 */ 6819static int 6820bitcpy(unsigned *p, unsigned q, unsigned mask) 6821{ 6822 unsigned before = *p; 6823 bitclr(p, mask); 6824 bitset(p, q & mask); 6825 return (before != *p); 6826} 6827 6828void 6829unparseputc1(XtermWidget xw, int c) 6830{ 6831 if (c >= 0x80 && c <= 0x9F) { 6832 if (!TScreenOf(xw)->control_eight_bits) { 6833 unparseputc(xw, A2E(ANSI_ESC)); 6834 c = A2E(c - 0x40); 6835 } 6836 } 6837 unparseputc(xw, c); 6838} 6839 6840void 6841unparseseq(XtermWidget xw, ANSI *ap) 6842{ 6843 int c; 6844 6845 unparseputc1(xw, c = ap->a_type); 6846 if (c == ANSI_ESC 6847 || c == ANSI_DCS 6848 || c == ANSI_CSI 6849 || c == ANSI_OSC 6850 || c == ANSI_PM 6851 || c == ANSI_APC 6852 || c == ANSI_SS3) { 6853 int i; 6854 int inters; 6855 6856 if (ap->a_pintro != 0) 6857 unparseputc(xw, ap->a_pintro); 6858 for (i = 0; i < ap->a_nparam; ++i) { 6859 if (i != 0) { 6860 if (ap->a_delim) { 6861 unparseputs(xw, ap->a_delim); 6862 } else { 6863 unparseputc(xw, ';'); 6864 } 6865 } 6866 if (ap->a_radix[i]) { 6867 char temp[8]; 6868 sprintf(temp, "%04X", ap->a_param[i] & 0xffff); 6869 unparseputs(xw, temp); 6870 } else { 6871 unparseputn(xw, (unsigned int) ap->a_param[i]); 6872 } 6873 } 6874 if ((inters = ap->a_inters) != 0) { 6875 for (i = 3; i >= 0; --i) { 6876 c = CharOf(inters >> (8 * i)); 6877 if (c != 0) 6878 unparseputc(xw, c); 6879 } 6880 } 6881 switch (ap->a_type) { 6882 case ANSI_DCS: 6883 /* FALLTHRU */ 6884 case ANSI_OSC: 6885 /* FALLTHRU */ 6886 case ANSI_PM: 6887 /* FALLTHRU */ 6888 case ANSI_APC: 6889 unparseputc1(xw, ANSI_ST); 6890 break; 6891 default: 6892 unparseputc(xw, (char) ap->a_final); 6893 break; 6894 } 6895 } 6896 unparse_end(xw); 6897} 6898 6899void 6900unparseputn(XtermWidget xw, unsigned int n) 6901{ 6902 unsigned int q; 6903 6904 q = n / 10; 6905 if (q != 0) 6906 unparseputn(xw, q); 6907 unparseputc(xw, (char) ('0' + (n % 10))); 6908} 6909 6910void 6911unparseputs(XtermWidget xw, const char *s) 6912{ 6913 if (s != 0) { 6914 while (*s) 6915 unparseputc(xw, *s++); 6916 } 6917} 6918 6919void 6920unparseputc(XtermWidget xw, int c) 6921{ 6922 TScreen *screen = TScreenOf(xw); 6923 IChar *buf = screen->unparse_bfr; 6924 unsigned len; 6925 6926 if ((screen->unparse_len + 2) >= sizeof(screen->unparse_bfr) / sizeof(IChar)) 6927 unparse_end(xw); 6928 6929 len = screen->unparse_len; 6930 6931#if OPT_TCAP_QUERY 6932 /* 6933 * If we're returning a termcap string, it has to be translated since 6934 * a DCS must not contain any characters except for the normal 7-bit 6935 * printable ASCII (counting tab, carriage return, etc). For now, 6936 * just use hexadecimal for the whole thing. 6937 */ 6938 if (screen->tc_query_code >= 0) { 6939 char tmp[3]; 6940 sprintf(tmp, "%02X", c & 0xFF); 6941 buf[len++] = CharOf(tmp[0]); 6942 buf[len++] = CharOf(tmp[1]); 6943 } else 6944#endif 6945 if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) { 6946 buf[len++] = '\n'; 6947 } 6948 6949 screen->unparse_len = len; 6950 6951 /* If send/receive mode is reset, we echo characters locally */ 6952 if ((xw->keyboard.flags & MODE_SRM) == 0) { 6953 (void) doparsing(xw, (unsigned) c, &myState); 6954 } 6955} 6956 6957void 6958unparse_end(XtermWidget xw) 6959{ 6960 TScreen *screen = TScreenOf(xw); 6961 6962 if (screen->unparse_len) { 6963#ifdef VMS 6964 tt_write(screen->unparse_bfr, screen->unparse_len); 6965#else /* VMS */ 6966 writePtyData(screen->respond, screen->unparse_bfr, screen->unparse_len); 6967#endif /* VMS */ 6968 screen->unparse_len = 0; 6969 } 6970} 6971 6972void 6973ToggleAlternate(XtermWidget xw) 6974{ 6975 if (TScreenOf(xw)->whichBuf) 6976 FromAlternate(xw); 6977 else 6978 ToAlternate(xw, False); 6979} 6980 6981static void 6982ToAlternate(XtermWidget xw, Bool clearFirst) 6983{ 6984 TScreen *screen = TScreenOf(xw); 6985 6986 if (screen->whichBuf == 0) { 6987 TRACE(("ToAlternate\n")); 6988 if (!screen->editBuf_index[1]) 6989 screen->editBuf_index[1] = allocScrnBuf(xw, 6990 (unsigned) MaxRows(screen), 6991 (unsigned) MaxCols(screen), 6992 &screen->editBuf_data[1]); 6993 SwitchBufs(xw, 1, clearFirst); 6994#if OPT_SAVE_LINES 6995 screen->visbuf = screen->editBuf_index[screen->whichBuf]; 6996#endif 6997 update_altscreen(); 6998 } 6999} 7000 7001static void 7002FromAlternate(XtermWidget xw) 7003{ 7004 TScreen *screen = TScreenOf(xw); 7005 7006 if (screen->whichBuf != 0) { 7007 TRACE(("FromAlternate\n")); 7008 if (screen->scroll_amt) 7009 FlushScroll(xw); 7010 SwitchBufs(xw, 0, False); 7011#if OPT_SAVE_LINES 7012 screen->visbuf = screen->editBuf_index[screen->whichBuf]; 7013#endif 7014 update_altscreen(); 7015 } 7016} 7017 7018static void 7019SwitchBufs(XtermWidget xw, int toBuf, Bool clearFirst) 7020{ 7021 TScreen *screen = TScreenOf(xw); 7022 int rows, top; 7023 7024 screen->whichBuf = toBuf; 7025 if (screen->cursor_state) 7026 HideCursor(); 7027 7028 rows = MaxRows(screen); 7029 SwitchBufPtrs(screen, toBuf); 7030 7031 if ((top = INX2ROW(screen, 0)) < rows) { 7032 if (screen->scroll_amt) { 7033 FlushScroll(xw); 7034 } 7035#if OPT_DOUBLE_BUFFER 7036 XFillRectangle(screen->display, 7037 VDrawable(screen), 7038 ReverseGC(xw, screen), 7039 (int) OriginX(screen), 7040 (int) top * FontHeight(screen) + screen->border, 7041 (unsigned) Width(screen), 7042 (unsigned) ((rows - top) * FontHeight(screen))); 7043#else 7044 XClearArea(screen->display, 7045 VWindow(screen), 7046 (int) OriginX(screen), 7047 (int) top * FontHeight(screen) + screen->border, 7048 (unsigned) Width(screen), 7049 (unsigned) ((rows - top) * FontHeight(screen)), 7050 False); 7051#endif 7052 if (clearFirst) { 7053 ClearBufRows(xw, top, rows); 7054 } 7055 } 7056 ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False); 7057} 7058 7059Bool 7060CheckBufPtrs(TScreen *screen) 7061{ 7062 return (screen->visbuf != 0 7063#if OPT_SAVE_LINES 7064 && screen->editBuf_index[0] != 0 7065#endif 7066 && screen->editBuf_index[1] != 0); 7067} 7068 7069/* 7070 * Swap buffer line pointers between alternate and regular screens. 7071 */ 7072void 7073SwitchBufPtrs(TScreen *screen, int toBuf GCC_UNUSED) 7074{ 7075 if (CheckBufPtrs(screen)) { 7076#if OPT_SAVE_LINES 7077 screen->visbuf = screen->editBuf_index[toBuf]; 7078#else 7079 size_t len = ScrnPointers(screen, (size_t) MaxRows(screen)); 7080 7081 memcpy(screen->save_ptr, screen->visbuf, len); 7082 memcpy(screen->visbuf, screen->editBuf_index[1], len); 7083 memcpy(screen->editBuf_index[1], screen->save_ptr, len); 7084#endif 7085 } 7086} 7087 7088void 7089VTRun(XtermWidget xw) 7090{ 7091 TScreen *screen = TScreenOf(xw); 7092 7093 TRACE(("VTRun ...\n")); 7094 7095 if (!screen->Vshow) { 7096 set_vt_visibility(True); 7097 } 7098 update_vttekmode(); 7099 update_vtshow(); 7100 update_tekshow(); 7101 set_vthide_sensitivity(); 7102 7103 ScrnAllocBuf(xw); 7104 7105 screen->cursor_state = OFF; 7106 screen->cursor_set = ON; 7107#if OPT_BLINK_CURS 7108 if (DoStartBlinking(screen)) 7109 StartBlinking(screen); 7110#endif 7111 7112#if OPT_TEK4014 7113 if (Tpushb > Tpushback) { 7114 fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback)); 7115 Tpushb = Tpushback; 7116 } 7117#endif 7118 screen->is_running = True; 7119 if (screen->embed_high && screen->embed_wide) { 7120 ScreenResize(xw, screen->embed_wide, screen->embed_high, &(xw->flags)); 7121 } 7122#if OPT_MAXIMIZE 7123 else if (resource.fullscreen == esTrue || resource.fullscreen == esAlways) 7124 FullScreen(term, True); 7125#endif 7126 if (!setjmp(VTend)) 7127 VTparse(xw); 7128 StopBlinking(screen); 7129 HideCursor(); 7130 screen->cursor_set = OFF; 7131 TRACE(("... VTRun\n")); 7132} 7133 7134/*ARGSUSED*/ 7135static void 7136VTExpose(Widget w GCC_UNUSED, 7137 XEvent *event, 7138 Region region GCC_UNUSED) 7139{ 7140 DEBUG_MSG("Expose\n"); 7141 if (event->type == Expose) 7142 HandleExposure(term, event); 7143} 7144 7145static void 7146VTGraphicsOrNoExpose(XEvent *event) 7147{ 7148 TScreen *screen = TScreenOf(term); 7149 if (screen->incopy <= 0) { 7150 screen->incopy = 1; 7151 if (screen->scrolls > 0) 7152 screen->scrolls--; 7153 } 7154 if (event->type == GraphicsExpose) 7155 if (HandleExposure(term, event)) 7156 screen->cursor_state = OFF; 7157 if ((event->type == NoExpose) 7158 || ((XGraphicsExposeEvent *) event)->count == 0) { 7159 if (screen->incopy <= 0 && screen->scrolls > 0) 7160 screen->scrolls--; 7161 if (screen->scrolls) 7162 screen->incopy = -1; 7163 else 7164 screen->incopy = 0; 7165 } 7166} 7167 7168/*ARGSUSED*/ 7169static void 7170VTNonMaskableEvent(Widget w GCC_UNUSED, 7171 XtPointer closure GCC_UNUSED, 7172 XEvent *event, 7173 Boolean *cont GCC_UNUSED) 7174{ 7175 switch (event->type) { 7176 case GraphicsExpose: 7177 /* FALLTHRU */ 7178 case NoExpose: 7179 VTGraphicsOrNoExpose(event); 7180 break; 7181 } 7182} 7183 7184static void 7185VTResize(Widget w) 7186{ 7187 if (XtIsRealized(w)) { 7188 XtermWidget xw = (XtermWidget) w; 7189 ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags); 7190 } 7191} 7192 7193#define okDimension(src,dst) ((src <= 32767) \ 7194 && ((dst = (Dimension) src) == src)) 7195 7196static void 7197RequestResize(XtermWidget xw, int rows, int cols, Bool text) 7198{ 7199 TScreen *screen = TScreenOf(xw); 7200 Dimension replyWidth, replyHeight; 7201 Dimension askedWidth, askedHeight; 7202 XtGeometryResult status; 7203 XWindowAttributes attrs; 7204 7205 TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text)); 7206 7207 /* check first if the row/column values fit into a Dimension */ 7208 if (cols > 0) { 7209 if ((int) (askedWidth = (Dimension) cols) < cols) { 7210 TRACE(("... cols too large for Dimension\n")); 7211 return; 7212 } 7213 } else { 7214 askedWidth = 0; 7215 } 7216 if (rows > 0) { 7217 if ((int) (askedHeight = (Dimension) rows) < rows) { 7218 TRACE(("... rows too large for Dimension\n")); 7219 return; 7220 } 7221 } else { 7222 askedHeight = 0; 7223 } 7224 7225 if (askedHeight == 0 7226 || askedWidth == 0 7227 || xw->misc.limit_resize > 0) { 7228 xtermGetWinAttrs(XtDisplay(xw), 7229 RootWindowOfScreen(XtScreen(xw)), &attrs); 7230 } 7231 7232 if (text) { 7233 unsigned long value; 7234 7235 if ((value = (unsigned long) rows) != 0) { 7236 if (rows < 0) 7237 value = (unsigned long) MaxRows(screen); 7238 value *= (unsigned long) FontHeight(screen); 7239 value += (unsigned long) (2 * screen->border); 7240 if (!okDimension(value, askedHeight)) 7241 return; 7242 } 7243 7244 if ((value = (unsigned long) cols) != 0) { 7245 if (cols < 0) 7246 value = (unsigned long) MaxCols(screen); 7247 value *= (unsigned long) FontWidth(screen); 7248 value += (unsigned long) ((2 * screen->border) 7249 + ScrollbarWidth(screen)); 7250 if (!okDimension(value, askedWidth)) 7251 return; 7252 } 7253 7254 } else { 7255 if (rows < 0) 7256 askedHeight = FullHeight(screen); 7257 if (cols < 0) 7258 askedWidth = FullWidth(screen); 7259 } 7260 7261 if (rows == 0) 7262 askedHeight = (Dimension) attrs.height; 7263 if (cols == 0) 7264 askedWidth = (Dimension) attrs.width; 7265 7266 if (xw->misc.limit_resize > 0) { 7267 Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height); 7268 Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width); 7269 if ((int) high < attrs.height) 7270 high = (Dimension) attrs.height; 7271 if (askedHeight > high) 7272 askedHeight = high; 7273 if ((int) wide < attrs.width) 7274 wide = (Dimension) attrs.width; 7275 if (askedWidth > wide) 7276 askedWidth = wide; 7277 } 7278#ifndef nothack 7279 getXtermSizeHints(xw); 7280#endif 7281 7282 TRACE(("...requesting resize %dx%d\n", askedHeight, askedWidth)); 7283 status = REQ_RESIZE((Widget) xw, 7284 askedWidth, askedHeight, 7285 &replyWidth, &replyHeight); 7286 7287 if (status == XtGeometryYes || 7288 status == XtGeometryDone) { 7289 ScreenResize(xw, replyWidth, replyHeight, &xw->flags); 7290 } 7291#ifndef nothack 7292 /* 7293 * XtMakeResizeRequest() has the undesirable side-effect of clearing 7294 * the window manager's hints, even on a failed request. This would 7295 * presumably be fixed if the shell did its own work. 7296 */ 7297 if (xw->hints.flags 7298 && replyHeight 7299 && replyWidth) { 7300 xw->hints.height = replyHeight; 7301 xw->hints.width = replyWidth; 7302 7303 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 7304 TRACE_HINTS(&xw->hints); 7305 XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); 7306 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 7307 TRACE_WM_HINTS(xw); 7308 } 7309#endif 7310 7311 XSync(screen->display, False); /* synchronize */ 7312 if (xtermAppPending()) 7313 xevents(); 7314 7315 TRACE(("...RequestResize done\n")); 7316} 7317 7318static String xterm_trans = 7319"<ClientMessage>WM_PROTOCOLS: DeleteWindow()\n\ 7320 <MappingNotify>: KeyboardMapping()\n"; 7321 7322int 7323VTInit(XtermWidget xw) 7324{ 7325 Widget vtparent = SHELL_OF(xw); 7326 7327 TRACE(("VTInit {{\n")); 7328 7329 XtRealizeWidget(vtparent); 7330 XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans)); 7331 (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent), 7332 &wm_delete_window, 1); 7333 TRACE_TRANS("shell", vtparent); 7334 TRACE_TRANS("vt100", (Widget) (xw)); 7335 7336 ScrnAllocBuf(xw); 7337 7338 TRACE(("...}} VTInit\n")); 7339 return (1); 7340} 7341 7342static void 7343VTClassInit(void) 7344{ 7345 XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity, 7346 (XtConvertArgList) NULL, (Cardinal) 0); 7347} 7348 7349#if OPT_COLOR_RES 7350/* 7351 * Override the use of XtDefaultForeground/XtDefaultBackground to make some 7352 * colors, such as cursor color, use the actual foreground/background value 7353 * if there is no explicit resource value used. 7354 */ 7355static Pixel 7356fill_Tres(XtermWidget target, XtermWidget source, int offset) 7357{ 7358 char *name; 7359 ScrnColors temp; 7360 TScreen *src = TScreenOf(source); 7361 TScreen *dst = TScreenOf(target); 7362 7363 dst->Tcolors[offset] = src->Tcolors[offset]; 7364 dst->Tcolors[offset].mode = False; 7365 7366 if ((name = x_strtrim(dst->Tcolors[offset].resource)) != 0) 7367 dst->Tcolors[offset].resource = name; 7368 7369 if (name == 0) { 7370 dst->Tcolors[offset].value = target->dft_foreground; 7371 } else if (isDefaultForeground(name)) { 7372 dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG) 7373 ? target->dft_foreground 7374 : dst->Tcolors[TEXT_FG].value); 7375 } else if (isDefaultBackground(name)) { 7376 dst->Tcolors[offset].value = ((offset == TEXT_FG || offset == TEXT_BG) 7377 ? target->dft_background 7378 : dst->Tcolors[TEXT_BG].value); 7379 } else { 7380 memset(&temp, 0, sizeof(temp)); 7381 if (AllocateTermColor(target, &temp, offset, name, True)) { 7382 if (COLOR_DEFINED(&(temp), offset)) 7383 free(temp.names[offset]); 7384 dst->Tcolors[offset].value = temp.colors[offset]; 7385 } else if (offset == TEXT_FG || offset == TEXT_BG) { 7386 free(name); 7387 dst->Tcolors[offset].resource = 0; 7388 } 7389 } 7390 return dst->Tcolors[offset].value; 7391} 7392 7393/* 7394 * If one or both of the foreground/background colors cannot be allocated, 7395 * e.g., due to gross misconfiguration, recover by setting both to the 7396 * display's default values. 7397 */ 7398static void 7399repairColors(XtermWidget target) 7400{ 7401 TScreen *screen = TScreenOf(target); 7402 7403 if (screen->Tcolors[TEXT_FG].resource == 0 || 7404 screen->Tcolors[TEXT_BG].resource == 0) { 7405 xtermWarning("unable to allocate fg/bg colors\n"); 7406 screen->Tcolors[TEXT_FG].resource = x_strdup(XtDefaultForeground); 7407 screen->Tcolors[TEXT_BG].resource = x_strdup(XtDefaultBackground); 7408 if (screen->Tcolors[TEXT_FG].resource == 0 || 7409 screen->Tcolors[TEXT_BG].resource == 0) { 7410 Exit(1); 7411 } 7412 screen->Tcolors[TEXT_FG].value = target->dft_foreground; 7413 screen->Tcolors[TEXT_BG].value = target->dft_background; 7414 } 7415} 7416#else 7417#define fill_Tres(target, source, offset) \ 7418 TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset] 7419#define repairColors(target) /* nothing */ 7420#endif 7421 7422#if OPT_WIDE_CHARS 7423static void 7424VTInitialize_locale(XtermWidget xw) 7425{ 7426 TScreen *screen = TScreenOf(xw); 7427 Bool is_utf8 = xtermEnvUTF8(); 7428 7429 TRACE(("VTInitialize_locale\n")); 7430 TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode)); 7431 TRACE(("... request screen.utf8_fonts = %d\n", screen->utf8_fonts)); 7432 7433 screen->utf8_always = (screen->utf8_mode == uAlways); 7434 if (screen->utf8_mode < 0) 7435 screen->utf8_mode = uFalse; 7436 7437 if (screen->utf8_mode > 3) 7438 screen->utf8_mode = uDefault; 7439 7440 screen->latin9_mode = 0; 7441 screen->unicode_font = 0; 7442#if OPT_LUIT_PROG 7443 xw->misc.callfilter = 0; 7444 xw->misc.use_encoding = 0; 7445 7446 TRACE(("... setup for luit:\n")); 7447 TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str)); 7448 7449 if (screen->utf8_mode == uFalse) { 7450 TRACE(("... command-line +u8 overrides\n")); 7451 } else 7452#if OPT_MINI_LUIT 7453 if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) { 7454 int fl = (int) strlen(DefaultFontN(xw)); 7455 if (fl > 11 7456 && x_strcasecmp(DefaultFontN(xw) + fl - 11, "-ISO10646-1") == 0) { 7457 screen->unicode_font = 1; 7458 /* unicode font, use True */ 7459#ifdef HAVE_LANGINFO_CODESET 7460 if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968") 7461 || !strcmp(xtermEnvEncoding(), "ISO-8859-1")) { 7462 if (screen->utf8_mode == uDefault) 7463 screen->utf8_mode = uFalse; 7464 } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) { 7465 if (screen->utf8_mode == uDefault) 7466 screen->utf8_mode = uFalse; 7467 screen->latin9_mode = 1; 7468 } else { 7469 xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1); 7470 screen->utf8_mode = uAlways; 7471 } 7472#else 7473 xw->misc.callfilter = is_utf8 ? 0 : 1; 7474 screen->utf8_mode = uAlways; 7475#endif 7476 } else { 7477 /* other encoding, use False */ 7478 if (screen->utf8_mode == uDefault) { 7479 screen->utf8_mode = is_utf8 ? uAlways : uFalse; 7480 } 7481 } 7482 } else 7483#endif /* OPT_MINI_LUIT */ 7484 if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 || 7485 x_strcasecmp(xw->misc.locale_str, "ON") == 0 || 7486 x_strcasecmp(xw->misc.locale_str, "YES") == 0 || 7487 x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 || 7488 strcmp(xw->misc.locale_str, "1") == 0) { 7489 /* when true ... fully obeying LC_CTYPE locale */ 7490 xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1); 7491 screen->utf8_mode = uAlways; 7492 } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 || 7493 x_strcasecmp(xw->misc.locale_str, "OFF") == 0 || 7494 x_strcasecmp(xw->misc.locale_str, "NO") == 0 || 7495 strcmp(xw->misc.locale_str, "0") == 0) { 7496 /* when false ... original value of utf8_mode is effective */ 7497 if (screen->utf8_mode == uDefault) { 7498 screen->utf8_mode = is_utf8 ? uAlways : uFalse; 7499 } 7500 } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 || 7501 x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) { 7502 /* when medium ... obeying locale only for UTF-8 and Asian */ 7503 if (is_utf8) { 7504 screen->utf8_mode = uAlways; 7505 } else if ( 7506#ifdef MB_CUR_MAX 7507 MB_CUR_MAX > 1 || 7508#else 7509 !strncmp(xtermEnvLocale(), "ja", (size_t) 2) || 7510 !strncmp(xtermEnvLocale(), "ko", (size_t) 2) || 7511 !strncmp(xtermEnvLocale(), "zh", (size_t) 2) || 7512#endif 7513 !strncmp(xtermEnvLocale(), "th", (size_t) 2) || 7514 !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) { 7515 xw->misc.callfilter = 1; 7516 screen->utf8_mode = uAlways; 7517 } else { 7518 screen->utf8_mode = uFalse; 7519 } 7520 } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 || 7521 x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) { 7522 /* when UTF-8 ... UTF-8 mode */ 7523 screen->utf8_mode = uAlways; 7524 } else { 7525 /* other words are regarded as encoding name passed to luit */ 7526 xw->misc.callfilter = 1; 7527 screen->utf8_mode = uAlways; 7528 xw->misc.use_encoding = 1; 7529 } 7530 TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter))); 7531 TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding))); 7532#else 7533 if (screen->utf8_mode == uDefault) { 7534 screen->utf8_mode = is_utf8 ? uAlways : uFalse; 7535 } 7536#endif /* OPT_LUIT_PROG */ 7537 7538 if (screen->utf8_fonts == uDefault) { 7539 switch (screen->utf8_mode) { 7540 case uFalse: 7541 /* FALLTHRU */ 7542 case uTrue: 7543 screen->utf8_fonts = screen->utf8_mode; 7544 break; 7545 case uDefault: 7546 /* should not happen */ 7547 screen->utf8_fonts = uTrue; 7548 break; 7549 case uAlways: 7550 /* use this to disable menu entry */ 7551 break; 7552 } 7553 } 7554 7555 screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse); 7556 7557 TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode)); 7558 TRACE(("... updated screen.utf8_fonts = %d\n", screen->utf8_fonts)); 7559 TRACE(("...VTInitialize_locale done\n")); 7560} 7561#endif 7562 7563void 7564lookupSelectUnit(XtermWidget xw, Cardinal item, String value) 7565{ 7566 /* *INDENT-OFF* */ 7567 static const struct { 7568 const char * name; 7569 SelectUnit code; 7570 } table[] = { 7571 { "char", Select_CHAR }, 7572 { "word", Select_WORD }, 7573 { "line", Select_LINE }, 7574 { "group", Select_GROUP }, 7575 { "page", Select_PAGE }, 7576 { "all", Select_ALL }, 7577#if OPT_SELECT_REGEX 7578 { "regex", Select_REGEX }, 7579#endif 7580 }; 7581 /* *INDENT-ON* */ 7582 7583 TScreen *screen = TScreenOf(xw); 7584 String next = x_skip_nonblanks(value); 7585 Cardinal n; 7586 7587 screen->selectMap[item] = NSELECTUNITS; 7588 for (n = 0; n < XtNumber(table); ++n) { 7589 if (!x_strncasecmp(table[n].name, value, (unsigned) (next - value))) { 7590 screen->selectMap[item] = table[n].code; 7591#if OPT_SELECT_REGEX 7592 if (table[n].code == Select_REGEX) { 7593 screen->selectExpr[item] = x_strtrim(next); 7594 TRACE(("Parsed regex \"%s\"\n", screen->selectExpr[item])); 7595 } 7596#endif 7597 break; 7598 } 7599 } 7600} 7601 7602static void 7603ParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item) 7604{ 7605 lookupSelectUnit(wnew, item, TScreenOf(wreq)->onClick[item]); 7606} 7607 7608/* 7609 * Parse a comma-separated list, returning a string which the caller must 7610 * free, and updating the source pointer. 7611 */ 7612static char * 7613ParseList(const char **source) 7614{ 7615 const char *base = *source; 7616 const char *next; 7617 char *value = 0; 7618 char *result; 7619 7620 /* ignore empty values */ 7621 while (*base == ',') 7622 ++base; 7623 7624 if (*base != '\0') { 7625 size_t size; 7626 7627 next = base; 7628 while (*next != '\0' && *next != ',') 7629 ++next; 7630 size = (size_t) (1 + next - base); 7631 value = malloc(size); 7632 if (value != 0) { 7633 memcpy(value, base, size); 7634 value[size - 1] = '\0'; 7635 } 7636 *source = next; 7637 } else { 7638 *source = base; 7639 } 7640 result = x_strtrim(value); 7641 free(value); 7642 return result; 7643} 7644 7645static void 7646set_flags_from_list(char *target, 7647 const char *source, 7648 const FlagList * list) 7649{ 7650 Cardinal n; 7651 int value = -1; 7652 7653 while (!IsEmpty(source)) { 7654 char *next = ParseList(&source); 7655 Boolean found = False; 7656 7657 if (next == 0) 7658 break; 7659 if (isdigit(CharOf(*next))) { 7660 char *temp; 7661 7662 value = (int) strtol(next, &temp, 0); 7663 if (!FullS2L(next, temp)) { 7664 xtermWarning("Expected a number: %s\n", next); 7665 } else { 7666 for (n = 0; list[n].name != 0; ++n) { 7667 if (list[n].code == value) { 7668 target[value] = 1; 7669 found = True; 7670 TRACE(("...found %s (%d)\n", list[n].name, value)); 7671 break; 7672 } 7673 } 7674 } 7675 } else { 7676 for (n = 0; list[n].name != 0; ++n) { 7677 if (!x_wildstrcmp(next, list[n].name)) { 7678 value = list[n].code; 7679 target[value] = 1; 7680 found = True; 7681 TRACE(("...found %s (%d)\n", list[n].name, value)); 7682 } 7683 } 7684 } 7685 if (!found) { 7686 xtermWarning("Unrecognized keyword: %s\n", next); 7687 } 7688 free(next); 7689 } 7690} 7691 7692#define InitCursorShape(target, source) \ 7693 target->cursor_shape = source->cursor_underline \ 7694 ? CURSOR_UNDERLINE \ 7695 : CURSOR_BLOCK 7696 7697/* ARGSUSED */ 7698static void 7699VTInitialize(Widget wrequest, 7700 Widget new_arg, 7701 ArgList args GCC_UNUSED, 7702 Cardinal *num_args GCC_UNUSED) 7703{ 7704#define Kolor(name) TScreenOf(wnew)->name.resource 7705#define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name)) 7706#define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name)) 7707#define DftFg(name) isDefaultForeground(Kolor(name)) 7708#define DftBg(name) isDefaultBackground(Kolor(name)) 7709 7710#define DATA_END { NULL, -1 } 7711#define DATA(name) { #name, ec##name } 7712 static const FlagList tblColorOps[] = 7713 { 7714 DATA(SetColor) 7715 ,DATA(GetColor) 7716 ,DATA(GetAnsiColor) 7717 ,DATA_END 7718 }; 7719#undef DATA 7720 7721#define DATA(name) { #name, ef##name } 7722 static const FlagList tblFontOps[] = 7723 { 7724 DATA(SetFont) 7725 ,DATA(GetFont) 7726 ,DATA_END 7727 }; 7728#undef DATA 7729 7730#define DATA(name) { #name, em##name } 7731 static const FlagList tblMouseOps[] = 7732 { 7733 DATA(X10) 7734 ,DATA(Locator) 7735 ,DATA(VT200Click) 7736 ,DATA(VT200Hilite) 7737 ,DATA(AnyButton) 7738 ,DATA(AnyEvent) 7739 ,DATA(FocusEvent) 7740 ,DATA(Extended) 7741 ,DATA(SGR) 7742 ,DATA(URXVT) 7743 ,DATA(AlternateScroll) 7744 ,DATA_END 7745 }; 7746#undef DATA 7747 7748#define DATA(name) { #name, et##name } 7749 static const FlagList tblTcapOps[] = 7750 { 7751 DATA(SetTcap) 7752 ,DATA(GetTcap) 7753 ,DATA_END 7754 }; 7755#undef DATA 7756 7757#define DATA(name) { #name, ew##name } 7758 static const FlagList tblWindowOps[] = 7759 { 7760 DATA(RestoreWin) 7761 ,DATA(MinimizeWin) 7762 ,DATA(SetWinPosition) 7763 ,DATA(SetWinSizePixels) 7764 ,DATA(RaiseWin) 7765 ,DATA(LowerWin) 7766 ,DATA(RefreshWin) 7767 ,DATA(SetWinSizeChars) 7768#if OPT_MAXIMIZE 7769 ,DATA(MaximizeWin) 7770 ,DATA(FullscreenWin) 7771#endif 7772 ,DATA(GetWinState) 7773 ,DATA(GetWinPosition) 7774 ,DATA(GetWinSizePixels) 7775 ,DATA(GetWinSizeChars) 7776#if OPT_MAXIMIZE 7777 ,DATA(GetScreenSizeChars) 7778#endif 7779 ,DATA(GetIconTitle) 7780 ,DATA(GetWinTitle) 7781 ,DATA(PushTitle) 7782 ,DATA(PopTitle) 7783 ,DATA(SetWinLines) 7784 ,DATA(SetXprop) 7785 ,DATA(GetSelection) 7786 ,DATA(SetSelection) 7787 ,DATA_END 7788 }; 7789#undef DATA 7790 7791#if OPT_RENDERFONT 7792#define DATA(name) { #name, er##name } 7793 static const FlagList tblRenderFont[] = 7794 { 7795 DATA(Default) 7796 ,DATA_END 7797 }; 7798#undef DATA 7799#endif 7800 7801#if OPT_WIDE_CHARS 7802#define DATA(name) { #name, u##name } 7803 static const FlagList tblUtf8Mode[] = 7804 { 7805 DATA(Always) 7806 ,DATA(Default) 7807 ,DATA_END 7808 }; 7809#undef DATA 7810#endif 7811 7812#ifndef NO_ACTIVE_ICON 7813#define DATA(name) { #name, ei##name } 7814 static const FlagList tblAIconOps[] = 7815 { 7816 DATA(Default) 7817 ,DATA_END 7818 }; 7819#undef DATA 7820#endif 7821 7822#define DATA(name) { #name, eb##name } 7823 static const FlagList tbl8BitMeta[] = 7824 { 7825 DATA(Never) 7826 ,DATA(Locale) 7827 ,DATA_END 7828 }; 7829#undef DATA 7830 7831 XtermWidget request = (XtermWidget) wrequest; 7832 XtermWidget wnew = (XtermWidget) new_arg; 7833 Widget my_parent = SHELL_OF(wnew); 7834 int i; 7835 const char *s; 7836 7837#if OPT_ISO_COLORS 7838 Bool color_ok; 7839#endif 7840 7841#if OPT_COLOR_RES2 7842 static XtResource fake_resources[] = 7843 { 7844#if OPT_256_COLORS 7845# include <256colres.h> 7846#elif OPT_88_COLORS 7847# include <88colres.h> 7848#endif 7849 }; 7850#endif /* OPT_COLOR_RES2 */ 7851 TScreen *screen = TScreenOf(wnew); 7852 7853#if OPT_TRACE 7854 check_tables(); 7855#endif 7856 7857 TRACE(("VTInitialize wnew %p, %d / %d resources\n", 7858 (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES)); 7859 assert(XtNumber(xterm_resources) < MAXRESOURCES); 7860 7861 /* Zero out the entire "screen" component of "wnew" widget, then do 7862 * field-by-field assignment of "screen" fields that are named in the 7863 * resource list. 7864 */ 7865 memset(screen, 0, sizeof(wnew->screen)); 7866 7867 /* DESCO Sys#67660 7868 * Zero out the entire "keyboard" component of "wnew" widget. 7869 */ 7870 memset(&wnew->keyboard, 0, sizeof(wnew->keyboard)); 7871 7872 /* 7873 * The workspace has no resources - clear it. 7874 */ 7875 memset(&wnew->work, 0, sizeof(wnew->work)); 7876 7877 /* dummy values so that we don't try to Realize the parent shell with height 7878 * or width of 0, which is illegal in X. The real size is computed in the 7879 * xtermWidget's Realize proc, but the shell's Realize proc is called first, 7880 * and must see a valid size. 7881 */ 7882 wnew->core.height = wnew->core.width = 1; 7883 7884 /* 7885 * The definition of -rv now is that it changes the definition of 7886 * XtDefaultForeground and XtDefaultBackground. So, we no longer 7887 * need to do anything special. 7888 */ 7889 screen->display = wnew->core.screen->display; 7890 7891 /* prep getVisualInfo() */ 7892 wnew->visInfo = 0; 7893 wnew->numVisuals = 0; 7894 (void) getVisualInfo(wnew); 7895 7896 /* 7897 * We use the default foreground/background colors to compare/check if a 7898 * color-resource has been set. 7899 */ 7900#define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy)) 7901#define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy)) 7902 7903 if (request->misc.re_verse) { 7904 wnew->dft_foreground = MyWhitePixel(screen->display); 7905 wnew->dft_background = MyBlackPixel(screen->display); 7906 } else { 7907 wnew->dft_foreground = MyBlackPixel(screen->display); 7908 wnew->dft_background = MyWhitePixel(screen->display); 7909 } 7910 7911 init_Tres(TEXT_FG); 7912 init_Tres(TEXT_BG); 7913 repairColors(wnew); 7914 7915 wnew->old_foreground = T_COLOR(screen, TEXT_FG); 7916 wnew->old_background = T_COLOR(screen, TEXT_BG); 7917 7918 TRACE(("Color resource initialization:\n")); 7919 TRACE((" Default foreground 0x%06lx\n", wnew->dft_foreground)); 7920 TRACE((" Default background 0x%06lx\n", wnew->dft_background)); 7921 TRACE((" Screen foreground 0x%06lx\n", T_COLOR(screen, TEXT_FG))); 7922 TRACE((" Screen background 0x%06lx\n", T_COLOR(screen, TEXT_BG))); 7923 TRACE((" Actual foreground 0x%06lx\n", wnew->old_foreground)); 7924 TRACE((" Actual background 0x%06lx\n", wnew->old_background)); 7925 7926 screen->mouse_button = 0; 7927 screen->mouse_row = -1; 7928 screen->mouse_col = -1; 7929 7930#if OPT_BOX_CHARS 7931 init_Bres(screen.force_box_chars); 7932 init_Bres(screen.force_packed); 7933 init_Bres(screen.force_all_chars); 7934 init_Bres(screen.assume_all_chars); 7935#endif 7936 init_Bres(screen.free_bold_box); 7937 init_Bres(screen.allowBoldFonts); 7938 7939 init_Bres(screen.c132); 7940 init_Bres(screen.curses); 7941 init_Bres(screen.hp_ll_bc); 7942#if OPT_XMC_GLITCH 7943 init_Ires(screen.xmc_glitch); 7944 init_Ires(screen.xmc_attributes); 7945 init_Bres(screen.xmc_inline); 7946 init_Bres(screen.move_sgr_ok); 7947#endif 7948#if OPT_BLINK_CURS 7949 init_Bres(screen.cursor_blink); 7950 init_Ires(screen.blink_on); 7951 init_Ires(screen.blink_off); 7952 screen->cursor_blink_res = screen->cursor_blink; 7953#endif 7954 init_Bres(screen.cursor_underline); 7955 /* resources allow for underline or block, not (yet) bar */ 7956 InitCursorShape(screen, TScreenOf(request)); 7957#if OPT_BLINK_CURS 7958 TRACE(("cursor_shape:%d blinks:%s\n", 7959 screen->cursor_shape, 7960 BtoS(screen->cursor_blink))); 7961#endif 7962#if OPT_BLINK_TEXT 7963 init_Ires(screen.blink_as_bold); 7964#endif 7965 init_Ires(screen.border); 7966 init_Bres(screen.jumpscroll); 7967 init_Bres(screen.fastscroll); 7968 7969 init_Bres(screen.old_fkeys); 7970 wnew->screen.old_fkeys0 = wnew->screen.old_fkeys; 7971 wnew->keyboard.type = screen->old_fkeys 7972 ? keyboardIsLegacy 7973 : keyboardIsDefault; 7974 7975 init_Mres(screen.delete_is_del); 7976#ifdef ALLOWLOGGING 7977 init_Bres(misc.logInhibit); 7978 init_Bres(misc.log_on); 7979 init_Sres(screen.logfile); 7980#endif 7981 init_Bres(screen.bellIsUrgent); 7982 init_Bres(screen.bellOnReset); 7983 init_Bres(screen.marginbell); 7984 init_Bres(screen.multiscroll); 7985 init_Ires(screen.nmarginbell); 7986 init_Ires(screen.savelines); 7987 init_Ires(screen.scrollBarBorder); 7988 init_Ires(screen.scrolllines); 7989 init_Bres(screen.alternateScroll); 7990 init_Bres(screen.scrollttyoutput); 7991 init_Bres(screen.scrollkey); 7992 7993 init_Dres(screen.scale_height); 7994 if (screen->scale_height < 0.9) 7995 screen->scale_height = (float) 0.9; 7996 if (screen->scale_height > 1.5) 7997 screen->scale_height = (float) 1.5; 7998 7999 init_Bres(misc.autoWrap); 8000 init_Bres(misc.login_shell); 8001 init_Bres(misc.reverseWrap); 8002 init_Bres(misc.scrollbar); 8003 init_Sres(misc.geo_metry); 8004 init_Sres(misc.T_geometry); 8005 8006 init_Sres(screen.term_id); 8007 for (s = TScreenOf(request)->term_id; *s; s++) { 8008 if (!isalpha(CharOf(*s))) 8009 break; 8010 } 8011 screen->terminal_id = atoi(s); 8012 if (screen->terminal_id < MIN_DECID) 8013 screen->terminal_id = MIN_DECID; 8014 if (screen->terminal_id > MAX_DECID) 8015 screen->terminal_id = MAX_DECID; 8016 TRACE(("term_id '%s' -> terminal_id %d\n", 8017 screen->term_id, 8018 screen->terminal_id)); 8019 8020 screen->vtXX_level = (screen->terminal_id / 100); 8021 8022 init_Ires(screen.title_modes); 8023 wnew->screen.title_modes0 = wnew->screen.title_modes; 8024 8025 init_Bres(screen.visualbell); 8026 init_Bres(screen.flash_line); 8027 init_Ires(screen.visualBellDelay); 8028 init_Bres(screen.poponbell); 8029 8030 init_Bres(screen.eraseSavedLines0); 8031 screen->eraseSavedLines = screen->eraseSavedLines0; 8032 8033 init_Ires(misc.limit_resize); 8034 8035#if OPT_NUM_LOCK 8036 init_Bres(misc.real_NumLock); 8037 init_Bres(misc.alwaysUseMods); 8038#endif 8039 8040#if OPT_INPUT_METHOD 8041 init_Bres(misc.open_im); 8042 init_Ires(misc.retry_im); 8043 init_Sres(misc.f_x); 8044 init_Sres(misc.input_method); 8045 init_Sres(misc.preedit_type); 8046#endif 8047 8048#if OPT_SHIFT_FONTS 8049 init_Bres(misc.shift_fonts); 8050#endif 8051#if OPT_SUNPC_KBD 8052 init_Ires(misc.ctrl_fkeys); 8053#endif 8054#if OPT_TEK4014 8055 TEK4014_SHOWN(wnew) = False; /* not a resource... */ 8056 init_Bres(misc.tekInhibit); 8057 init_Bres(misc.tekSmall); 8058 init_Bres(misc.TekEmu); 8059#endif 8060#if OPT_TCAP_QUERY 8061 screen->tc_query_code = -1; 8062#endif 8063 wnew->misc.re_verse0 = request->misc.re_verse; 8064 init_Bres(misc.re_verse); 8065 init_Ires(screen.multiClickTime); 8066 init_Ires(screen.bellSuppressTime); 8067 init_Sres(screen.charClass); 8068 8069 init_Bres(screen.always_highlight); 8070 init_Bres(screen.brokenSelections); 8071 init_Bres(screen.cutNewline); 8072 init_Bres(screen.cutToBeginningOfLine); 8073 init_Bres(screen.highlight_selection); 8074 init_Bres(screen.show_wrap_marks); 8075 init_Bres(screen.i18nSelections); 8076 init_Bres(screen.keepClipboard); 8077 init_Bres(screen.keepSelection); 8078 init_Bres(screen.selectToClipboard); 8079 init_Bres(screen.trim_selection); 8080 8081 screen->pointer_cursor = TScreenOf(request)->pointer_cursor; 8082 init_Ires(screen.pointer_mode); 8083 wnew->screen.pointer_mode0 = wnew->screen.pointer_mode; 8084 8085 init_Sres(screen.answer_back); 8086 8087 wnew->SPS.printer_checked = False; 8088 init_Sres(SPS.printer_command); 8089 init_Bres(SPS.printer_autoclose); 8090 init_Bres(SPS.printer_extent); 8091 init_Bres(SPS.printer_formfeed); 8092 init_Bres(SPS.printer_newline); 8093 init_Ires(SPS.printer_controlmode); 8094#if OPT_PRINT_COLORS 8095 init_Ires(SPS.print_attributes); 8096#endif 8097 8098 init_Sres(screen.keyboard_dialect); 8099 8100 init_Bres(screen.input_eight_bits); 8101 init_Bres(screen.output_eight_bits); 8102 init_Bres(screen.control_eight_bits); 8103 init_Bres(screen.backarrow_key); 8104 init_Bres(screen.alt_is_not_meta); 8105 init_Bres(screen.alt_sends_esc); 8106 init_Bres(screen.meta_sends_esc); 8107 8108 init_Bres(screen.allowPasteControl0); 8109 init_Bres(screen.allowSendEvent0); 8110 init_Bres(screen.allowColorOp0); 8111 init_Bres(screen.allowFontOp0); 8112 init_Bres(screen.allowMouseOp0); 8113 init_Bres(screen.allowTcapOp0); 8114 init_Bres(screen.allowTitleOp0); 8115 init_Bres(screen.allowWindowOp0); 8116 8117#if OPT_SCROLL_LOCK 8118 init_Bres(screen.allowScrollLock0); 8119#endif 8120 8121 init_Sres(screen.disallowedColorOps); 8122 8123 set_flags_from_list(screen->disallow_color_ops, 8124 screen->disallowedColorOps, 8125 tblColorOps); 8126 8127 init_Sres(screen.disallowedFontOps); 8128 8129 set_flags_from_list(screen->disallow_font_ops, 8130 screen->disallowedFontOps, 8131 tblFontOps); 8132 8133 init_Sres(screen.disallowedMouseOps); 8134 8135 set_flags_from_list(screen->disallow_mouse_ops, 8136 screen->disallowedMouseOps, 8137 tblMouseOps); 8138 8139 init_Sres(screen.disallowedTcapOps); 8140 8141 set_flags_from_list(screen->disallow_tcap_ops, 8142 screen->disallowedTcapOps, 8143 tblTcapOps); 8144 8145 init_Sres(screen.disallowedWinOps); 8146 8147 set_flags_from_list(screen->disallow_win_ops, 8148 screen->disallowedWinOps, 8149 tblWindowOps); 8150 8151 init_Sres(screen.default_string); 8152 init_Sres(screen.eightbit_select_types); 8153#if OPT_WIDE_CHARS 8154 init_Sres(screen.utf8_select_types); 8155#endif 8156 8157 /* make a copy so that editres cannot change the resource after startup */ 8158 screen->allowPasteControls = screen->allowPasteControl0; 8159 screen->allowSendEvents = screen->allowSendEvent0; 8160 screen->allowColorOps = screen->allowColorOp0; 8161 screen->allowFontOps = screen->allowFontOp0; 8162 screen->allowMouseOps = screen->allowMouseOp0; 8163 screen->allowTcapOps = screen->allowTcapOp0; 8164 screen->allowTitleOps = screen->allowTitleOp0; 8165 screen->allowWindowOps = screen->allowWindowOp0; 8166 8167#if OPT_SCROLL_LOCK 8168 screen->allowScrollLock = screen->allowScrollLock0; 8169#endif 8170 8171 init_Bres(screen.quiet_grab); 8172 8173#ifndef NO_ACTIVE_ICON 8174 init_Sres(screen.icon_fontname); 8175 getIconicFont(screen)->fs = XLoadQueryFont(screen->display, 8176 screen->icon_fontname); 8177 TRACE(("iconFont '%s' %sloaded successfully\n", 8178 screen->icon_fontname, 8179 getIconicFont(screen)->fs ? "" : "NOT ")); 8180 init_Sres(misc.active_icon_s); 8181 wnew->work.active_icon = 8182 (Boolean) extendedBoolean(wnew->misc.active_icon_s, 8183 tblAIconOps, eiLAST); 8184 init_Ires(misc.icon_border_width); 8185 wnew->misc.icon_border_pixel = request->misc.icon_border_pixel; 8186#endif /* NO_ACTIVE_ICON */ 8187 8188 init_Bres(misc.signalInhibit); 8189 init_Bres(misc.titeInhibit); 8190 init_Bres(misc.tiXtraScroll); 8191 init_Bres(misc.cdXtraScroll); 8192 init_Bres(misc.dynamicColors); 8193 8194#if OPT_DEC_CHRSET 8195 for (i = 0; i < NUM_CHRSET; i++) { 8196 screen->double_fonts[i].warn = fwResource; 8197 } 8198#endif 8199 for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) { 8200 init_Sres2(screen.MenuFontName, i); 8201 } 8202 for (i = 0; i < fMAX; i++) { 8203 screen->fnts[i].warn = fwResource; 8204#if OPT_WIDE_ATTRS 8205 screen->ifnts[i].warn = fwResource; 8206#endif 8207 } 8208#ifndef NO_ACTIVE_ICON 8209 screen->fnt_icon.warn = fwResource; 8210#endif 8211 8212 init_Ires(misc.fontWarnings); 8213 8214 initFontLists(wnew); 8215 8216#define DefaultFontNames screen->menu_font_names[fontMenu_default] 8217 8218 /* 8219 * Process Xft font resources first, since faceName may contain X11 fonts 8220 * that should override the "font" resource. 8221 */ 8222#if OPT_RENDERFONT 8223 for (i = 0; i <= fontMenu_lastBuiltin; ++i) { 8224 init_Dres2(misc.face_size, i); 8225 } 8226 8227#define ALLOC_FONTLIST(name,which,field) \ 8228 init_Sres(misc.default_xft.field);\ 8229 allocFontList(wnew,\ 8230 name,\ 8231 &(wnew->work.fonts),\ 8232 which,\ 8233 wnew->misc.default_xft.field,\ 8234 True) 8235 8236 ALLOC_FONTLIST(XtNfaceName, fNorm, f_n); 8237 8238#if OPT_WIDE_CHARS 8239 ALLOC_FONTLIST(XtNfaceNameDoublesize, fWide, f_w); 8240#endif 8241 8242#undef ALLOC_FONTLIST 8243 8244#endif 8245 8246 /* 8247 * Process X11 (XLFD) font specifications. 8248 */ 8249#define ALLOC_FONTLIST(name,which,field) \ 8250 init_Sres(misc.default_font.field);\ 8251 allocFontList(wnew,\ 8252 name,\ 8253 &(wnew->work.fonts),\ 8254 which,\ 8255 wnew->misc.default_font.field,\ 8256 False) 8257 8258 ALLOC_FONTLIST(XtNfont, fNorm, f_n); 8259 ALLOC_FONTLIST(XtNboldFont, fBold, f_b); 8260 8261 DefaultFontNames[fNorm] = x_strdup(DefaultFontN(wnew)); 8262 DefaultFontNames[fBold] = x_strdup(DefaultFontB(wnew)); 8263 8264#if OPT_WIDE_CHARS 8265 ALLOC_FONTLIST(XtNwideFont, fWide, f_w); 8266 ALLOC_FONTLIST(XtNwideBoldFont, fWBold, f_wb); 8267 8268 DefaultFontNames[fWide] = x_strdup(DefaultFontW(wnew)); 8269 DefaultFontNames[fWBold] = x_strdup(DefaultFontWB(wnew)); 8270#endif 8271 8272#undef ALLOC_FONTLIST 8273 8274 screen->EscapeFontName() = NULL; 8275 screen->SelectFontName() = NULL; 8276 8277 screen->menu_font_number = fontMenu_default; 8278 init_Sres(screen.initial_font); 8279 if (screen->initial_font != 0) { 8280 int result = xtermGetFont(screen->initial_font); 8281 if (result >= 0) 8282 screen->menu_font_number = result; 8283 } 8284#if OPT_BROKEN_OSC 8285 init_Bres(screen.brokenLinuxOSC); 8286#endif 8287 8288#if OPT_BROKEN_ST 8289 init_Bres(screen.brokenStringTerm); 8290#endif 8291 8292#if OPT_C1_PRINT 8293 init_Bres(screen.c1_printable); 8294#endif 8295 8296#if OPT_CLIP_BOLD 8297 init_Bres(screen.use_clipping); 8298#endif 8299 8300#if OPT_DEC_CHRSET 8301 init_Bres(screen.font_doublesize); 8302 init_Ires(screen.cache_doublesize); 8303 if (screen->cache_doublesize > NUM_CHRSET) 8304 screen->cache_doublesize = NUM_CHRSET; 8305 if (screen->cache_doublesize == 0) 8306 screen->font_doublesize = False; 8307 TRACE(("Doublesize%s enabled, up to %d fonts\n", 8308 screen->font_doublesize ? "" : " not", 8309 screen->cache_doublesize)); 8310#endif 8311 8312#if OPT_ISO_COLORS 8313 init_Ires(screen.veryBoldColors); 8314 init_Bres(screen.boldColors); 8315 init_Bres(screen.colorAttrMode); 8316 init_Bres(screen.colorBDMode); 8317 init_Bres(screen.colorBLMode); 8318 init_Bres(screen.colorMode); 8319 init_Bres(screen.colorULMode); 8320 init_Bres(screen.italicULMode); 8321 init_Bres(screen.colorRVMode); 8322 8323#if OPT_WIDE_ATTRS 8324 init_Bres(screen.colorITMode); 8325#endif 8326 8327#if OPT_COLOR_RES2 8328 TRACE(("...will fake resources for color%d to color%d\n", 8329 MIN_ANSI_COLORS, 8330 NUM_ANSI_COLORS - 1)); 8331#endif 8332 for (i = 0, color_ok = False; i < MAXCOLORS; i++) { 8333 8334#if OPT_COLOR_RES2 8335 /* 8336 * Xt has a hardcoded limit on the maximum number of resources that can 8337 * be used in a widget. If we configure both luit (which implies 8338 * wide-characters) and 256-colors, it goes over that limit. Most 8339 * people would not need a resource-file with 256-colors; the default 8340 * values in our table are sufficient. In that case, fake the resource 8341 * setting by copying the default value from the table. The #define's 8342 * can be overridden to make these true resources. 8343 */ 8344 if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) { 8345 screen->Acolors[i].resource = 8346 x_strtrim(fake_resources[i - MIN_ANSI_COLORS].default_addr); 8347 if (screen->Acolors[i].resource == 0) 8348 screen->Acolors[i].resource = XtDefaultForeground; 8349 } else 8350#endif /* OPT_COLOR_RES2 */ 8351 { 8352 screen->Acolors[i] = TScreenOf(request)->Acolors[i]; 8353 screen->Acolors[i].resource = 8354 x_strtrim(screen->Acolors[i].resource); 8355 } 8356 8357#if OPT_COLOR_RES 8358 TRACE(("Acolors[%d] = %s\n", i, screen->Acolors[i].resource)); 8359 screen->Acolors[i].mode = False; 8360 if (DftFg(Acolors[i])) { 8361 screen->Acolors[i].value = T_COLOR(screen, TEXT_FG); 8362 screen->Acolors[i].mode = True; 8363 } else if (DftBg(Acolors[i])) { 8364 screen->Acolors[i].value = T_COLOR(screen, TEXT_BG); 8365 screen->Acolors[i].mode = True; 8366 } else { 8367 color_ok = True; 8368 } 8369#else 8370 TRACE(("Acolors[%d] = %#lx\n", i, TScreenOf(request)->Acolors[i])); 8371 if (screen->Acolors[i] != wnew->dft_foreground && 8372 screen->Acolors[i] != T_COLOR(screen, TEXT_FG) && 8373 screen->Acolors[i] != T_COLOR(screen, TEXT_BG)) 8374 color_ok = True; 8375#endif 8376 } 8377 8378 /* 8379 * Check if we're trying to use color in a monochrome screen. Disable 8380 * color in that case, since that would make ANSI colors unusable. A 4-bit 8381 * or 8-bit display is usable, so we do not have to check for anything more 8382 * specific. 8383 */ 8384 if (color_ok) { 8385 if (getVisualDepth(wnew) <= 1) { 8386 TRACE(("disabling color since screen is monochrome\n")); 8387 color_ok = False; 8388 } 8389 } 8390 8391 /* If none of the colors are anything other than the foreground or 8392 * background, we'll assume this isn't color, no matter what the colorMode 8393 * resource says. (There doesn't seem to be any good way to determine if 8394 * the resource lookup failed versus the user having misconfigured this). 8395 */ 8396 if (!color_ok) { 8397 screen->colorMode = False; 8398 TRACE(("All colors are foreground or background: disable colorMode\n")); 8399 } 8400 wnew->sgr_foreground = -1; 8401 wnew->sgr_background = -1; 8402 wnew->sgr_extended = False; 8403#endif /* OPT_ISO_COLORS */ 8404 8405 /* 8406 * Decode the resources that control the behavior on multiple mouse clicks. 8407 * A single click is always bound to normal character selection, but the 8408 * other flavors can be changed. 8409 */ 8410 for (i = 0; i < NSELECTUNITS; ++i) { 8411 int ck = (i + 1); 8412 screen->maxClicks = ck; 8413 if (i == Select_CHAR) 8414 screen->selectMap[i] = Select_CHAR; 8415 else if (TScreenOf(request)->onClick[i] != 0) 8416 ParseOnClicks(wnew, request, (unsigned) i); 8417 else if (i <= Select_LINE) 8418 screen->selectMap[i] = (SelectUnit) i; 8419 else 8420 break; 8421 TRACE(("on%dClicks %s=%d\n", ck, 8422 NonNull(TScreenOf(request)->onClick[i]), 8423 screen->selectMap[i])); 8424 if (screen->selectMap[i] == NSELECTUNITS) 8425 break; 8426 } 8427 TRACE(("maxClicks %d\n", screen->maxClicks)); 8428 8429 init_Tres(MOUSE_FG); 8430 init_Tres(MOUSE_BG); 8431 init_Tres(TEXT_CURSOR); 8432#if OPT_HIGHLIGHT_COLOR 8433 init_Tres(HIGHLIGHT_BG); 8434 init_Tres(HIGHLIGHT_FG); 8435 init_Bres(screen.hilite_reverse); 8436 init_Mres(screen.hilite_color); 8437 if (screen->hilite_color == Maybe) { 8438 screen->hilite_color = False; 8439#if OPT_COLOR_RES 8440 /* 8441 * If the highlight text/background are both set, and if they are 8442 * not equal to either the text/background or background/text, then 8443 * set the highlightColorMode automatically. 8444 */ 8445 if (!DftFg(Tcolors[HIGHLIGHT_BG]) 8446 && !DftBg(Tcolors[HIGHLIGHT_FG]) 8447 && !TxtFg(Tcolors[HIGHLIGHT_BG]) 8448 && !TxtBg(Tcolors[HIGHLIGHT_FG]) 8449 && !TxtBg(Tcolors[HIGHLIGHT_BG]) 8450 && !TxtFg(Tcolors[HIGHLIGHT_FG])) { 8451 TRACE(("...setting hilite_color automatically\n")); 8452 screen->hilite_color = True; 8453 } 8454#endif 8455 } 8456#endif 8457 8458#if OPT_TEK4014 8459 /* 8460 * The Tek4014 window has no separate resources for foreground, background 8461 * and cursor color. Since xterm always creates the vt100 widget first, we 8462 * can set the Tektronix colors here. That lets us use escape sequences to 8463 * set its dynamic colors and get consistent behavior whether or not the 8464 * window is displayed. 8465 */ 8466 screen->Tcolors[TEK_BG] = screen->Tcolors[TEXT_BG]; 8467 screen->Tcolors[TEK_FG] = screen->Tcolors[TEXT_FG]; 8468 screen->Tcolors[TEK_CURSOR] = screen->Tcolors[TEXT_CURSOR]; 8469#endif 8470 8471#ifdef SCROLLBAR_RIGHT 8472 init_Bres(misc.useRight); 8473#endif 8474 8475#if OPT_RENDERFONT 8476 init_Sres(misc.render_font_s); 8477 wnew->work.render_font = 8478 (Boolean) extendedBoolean(wnew->misc.render_font_s, 8479 tblRenderFont, erLast); 8480 if (wnew->work.render_font == erDefault) { 8481 if (IsEmpty(CurrentXftFont(wnew))) { 8482 free((void *) CurrentXftFont(wnew)); 8483 CurrentXftFont(wnew) = x_strdup(DEFFACENAME_AUTO); 8484 TRACE(("will allow runtime switch to render_font using \"%s\"\n", 8485 CurrentXftFont(wnew))); 8486 } else { 8487 wnew->work.render_font = erTrue; 8488 TRACE(("initially using TrueType font\n")); 8489 } 8490 } 8491 /* minor tweak to make debug traces consistent: */ 8492 if (wnew->work.render_font) { 8493 if (IsEmpty(CurrentXftFont(wnew))) { 8494 wnew->work.render_font = False; 8495 TRACE(("reset render_font since there is no face_name\n")); 8496 } 8497 } 8498#endif 8499 8500#if OPT_WIDE_CHARS 8501 /* setup data for next call */ 8502 request->screen.utf8_mode = 8503 extendedBoolean(request->screen.utf8_mode_s, tblUtf8Mode, uLast); 8504 request->screen.utf8_fonts = 8505 extendedBoolean(request->screen.utf8_fonts_s, tblUtf8Mode, uLast); 8506 8507 /* 8508 * Make a copy in the input/request so that DefaultFontN() works for 8509 * the "CHECKFONT" option. 8510 */ 8511 copyFontList(&(request->work.fonts.x11.list_n), 8512 wnew->work.fonts.x11.list_n); 8513 8514 VTInitialize_locale(request); 8515 init_Bres(screen.normalized_c); 8516 init_Bres(screen.utf8_latin1); 8517 init_Bres(screen.utf8_title); 8518 8519#if OPT_LUIT_PROG 8520 init_Bres(misc.callfilter); 8521 init_Bres(misc.use_encoding); 8522 init_Sres(misc.locale_str); 8523 init_Sres(misc.localefilter); 8524#endif 8525 8526 init_Ires(screen.utf8_inparse); 8527 init_Ires(screen.utf8_mode); 8528 init_Ires(screen.utf8_fonts); 8529 init_Ires(screen.max_combining); 8530 8531 init_Ires(screen.utf8_always); /* from utf8_mode, used in doparse */ 8532 8533 if (screen->max_combining < 0) { 8534 screen->max_combining = 0; 8535 } 8536 if (screen->max_combining > 5) { 8537 screen->max_combining = 5; 8538 } 8539 8540 init_Bres(screen.vt100_graphics); 8541 init_Bres(screen.wide_chars); 8542 init_Bres(misc.mk_width); 8543 init_Bres(misc.cjk_width); 8544 8545 init_Ires(misc.mk_samplesize); 8546 init_Ires(misc.mk_samplepass); 8547 8548 if (wnew->misc.mk_samplesize > 0xffff) 8549 wnew->misc.mk_samplesize = 0xffff; 8550 if (wnew->misc.mk_samplesize < 0) 8551 wnew->misc.mk_samplesize = 0; 8552 8553 if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize) 8554 wnew->misc.mk_samplepass = wnew->misc.mk_samplesize; 8555 if (wnew->misc.mk_samplepass < 0) 8556 wnew->misc.mk_samplepass = 0; 8557 8558 if (TScreenOf(request)->utf8_mode) { 8559 TRACE(("setting wide_chars on\n")); 8560 screen->wide_chars = True; 8561 } else { 8562 TRACE(("setting utf8_mode to 0\n")); 8563 screen->utf8_mode = uFalse; 8564 } 8565 mk_wcwidth_init(screen->utf8_mode); 8566 TRACE(("initialized UTF-8 mode to %d\n", screen->utf8_mode)); 8567 8568#if OPT_MINI_LUIT 8569 if (TScreenOf(request)->latin9_mode) { 8570 screen->latin9_mode = True; 8571 } 8572 if (TScreenOf(request)->unicode_font) { 8573 screen->unicode_font = True; 8574 } 8575 TRACE(("initialized Latin9 mode to %d\n", screen->latin9_mode)); 8576 TRACE(("initialized unicode_font to %d\n", screen->unicode_font)); 8577#endif 8578 8579 decode_wcwidth(wnew); 8580 xtermSaveVTFonts(wnew); 8581#endif /* OPT_WIDE_CHARS */ 8582 8583 init_Sres(screen.eight_bit_meta_s); 8584 wnew->screen.eight_bit_meta = 8585 extendedBoolean(request->screen.eight_bit_meta_s, tbl8BitMeta, uLast); 8586 if (wnew->screen.eight_bit_meta == ebLocale) { 8587#if OPT_WIDE_CHARS 8588 if (xtermEnvUTF8()) { 8589 wnew->screen.eight_bit_meta = ebFalse; 8590 TRACE(("...eightBitMeta is false due to locale\n")); 8591 } else 8592#endif /* OPT_WIDE_CHARS */ 8593 { 8594 wnew->screen.eight_bit_meta = ebTrue; 8595 TRACE(("...eightBitMeta is true due to locale\n")); 8596 } 8597 } 8598 8599 init_Bres(screen.always_bold_mode); 8600 init_Bres(screen.bold_mode); 8601 init_Bres(screen.underline); 8602 8603 wnew->cur_foreground = 0; 8604 wnew->cur_background = 0; 8605 8606 wnew->keyboard.flags = MODE_SRM; 8607 8608 if (screen->backarrow_key) 8609 wnew->keyboard.flags |= MODE_DECBKM; 8610 TRACE(("initialized DECBKM %s\n", 8611 BtoS(wnew->keyboard.flags & MODE_DECBKM))); 8612 8613#if OPT_SIXEL_GRAPHICS 8614 init_Bres(screen.sixel_scrolling); 8615 if (screen->sixel_scrolling) 8616 wnew->keyboard.flags |= MODE_DECSDM; 8617 TRACE(("initialized DECSDM %s\n", 8618 BtoS(wnew->keyboard.flags & MODE_DECSDM))); 8619#endif 8620 8621#if OPT_GRAPHICS 8622 init_Ires(screen.numcolorregisters); 8623 TRACE(("initialized NUM_COLOR_REGISTERS to resource default: %d\n", 8624 screen->numcolorregisters)); 8625 8626 init_Bres(screen.privatecolorregisters); /* FIXME: should this be off unconditionally here? */ 8627 TRACE(("initialized PRIVATE_COLOR_REGISTERS to resource default: %s\n", 8628 BtoS(screen->privatecolorregisters))); 8629#endif 8630 8631#if OPT_GRAPHICS 8632 { 8633 int native_w, native_h; 8634 8635 switch (screen->terminal_id) { 8636 case 125: 8637 native_w = 768; 8638 native_h = 460; 8639 break; 8640 case 240: 8641 native_w = 800; 8642 native_h = 460; 8643 break; 8644 case 241: 8645 native_w = 800; 8646 native_h = 460; 8647 break; 8648 case 330: 8649 native_w = 800; 8650 native_h = 480; 8651 break; 8652 case 340: 8653 /* FALLTHRU */ 8654 default: 8655 native_w = 800; 8656 native_h = 480; 8657 break; 8658 case 382: 8659 native_w = 960; 8660 native_h = 750; 8661 break; 8662 } 8663 8664# if OPT_REGIS_GRAPHICS 8665 init_Sres(screen.graphics_regis_default_font); 8666 TRACE(("default ReGIS font: %s\n", 8667 screen->graphics_regis_default_font)); 8668 8669 init_Sres(screen.graphics_regis_screensize); 8670 screen->graphics_regis_def_high = 1000; 8671 screen->graphics_regis_def_wide = 1000; 8672 if (!x_strcasecmp(screen->graphics_regis_screensize, "auto")) { 8673 TRACE(("setting default ReGIS screensize based on terminal_id %d\n", 8674 screen->terminal_id)); 8675 screen->graphics_regis_def_high = (Dimension) native_w; 8676 screen->graphics_regis_def_wide = (Dimension) native_h; 8677 } else { 8678 int conf_high; 8679 int conf_wide; 8680 char ignore; 8681 8682 if (sscanf(screen->graphics_regis_screensize, 8683 "%dx%d%c", 8684 &conf_wide, 8685 &conf_high, 8686 &ignore) == 2) { 8687 if (conf_high > 0 && conf_wide > 0) { 8688 screen->graphics_regis_def_high = 8689 (Dimension) conf_high; 8690 screen->graphics_regis_def_wide = 8691 (Dimension) conf_wide; 8692 } else { 8693 TRACE(("ignoring invalid regisScreenSize %s\n", 8694 screen->graphics_regis_screensize)); 8695 } 8696 } else { 8697 TRACE(("ignoring invalid regisScreenSize %s\n", 8698 screen->graphics_regis_screensize)); 8699 } 8700 } 8701 TRACE(("default ReGIS graphics screensize %dx%d\n", 8702 (int) screen->graphics_regis_def_wide, 8703 (int) screen->graphics_regis_def_high)); 8704# endif 8705 8706 init_Sres(screen.graphics_max_size); 8707 screen->graphics_max_high = 1000; 8708 screen->graphics_max_wide = 1000; 8709 if (!x_strcasecmp(screen->graphics_max_size, "auto")) { 8710 TRACE(("setting max graphics screensize based on terminal_id %d\n", 8711 screen->terminal_id)); 8712 screen->graphics_max_high = (Dimension) native_w; 8713 screen->graphics_max_wide = (Dimension) native_h; 8714 } else { 8715 int conf_high; 8716 int conf_wide; 8717 char ignore; 8718 8719 if (sscanf(screen->graphics_max_size, 8720 "%dx%d%c", 8721 &conf_wide, 8722 &conf_high, 8723 &ignore) == 2) { 8724 if (conf_high > 0 && conf_wide > 0) { 8725 screen->graphics_max_high = (Dimension) conf_high; 8726 screen->graphics_max_wide = (Dimension) conf_wide; 8727 } else { 8728 TRACE(("ignoring invalid maxGraphicSize %s\n", 8729 screen->graphics_max_size)); 8730 } 8731 } else { 8732 TRACE(("ignoring invalid maxGraphicSize %s\n", 8733 screen->graphics_max_size)); 8734 } 8735 } 8736# if OPT_REGIS_GRAPHICS 8737 /* Make sure the max is large enough for the default ReGIS size. */ 8738 if (screen->graphics_regis_def_high > 8739 screen->graphics_max_high) { 8740 screen->graphics_max_high = 8741 screen->graphics_regis_def_high; 8742 } 8743 if (screen->graphics_regis_def_wide > 8744 screen->graphics_max_wide) { 8745 screen->graphics_max_wide = 8746 screen->graphics_regis_def_wide; 8747 } 8748# endif 8749 TRACE(("max graphics screensize %dx%d\n", 8750 (int) screen->graphics_max_wide, 8751 (int) screen->graphics_max_high)); 8752 } 8753#endif 8754 8755#if OPT_SIXEL_GRAPHICS 8756 init_Bres(screen.sixel_scrolls_right); 8757 TRACE(("initialized SIXEL_SCROLLS_RIGHT to resource default: %s\n", 8758 BtoS(screen->sixel_scrolls_right))); 8759#endif 8760 8761 /* look for focus related events on the shell, because we need 8762 * to care about the shell's border being part of our focus. 8763 */ 8764 TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent)); 8765 XtAddEventHandler(my_parent, EnterWindowMask, False, 8766 HandleEnterWindow, (Opaque) NULL); 8767 XtAddEventHandler(my_parent, LeaveWindowMask, False, 8768 HandleLeaveWindow, (Opaque) NULL); 8769 XtAddEventHandler(my_parent, FocusChangeMask, False, 8770 HandleFocusChange, (Opaque) NULL); 8771 XtAddEventHandler((Widget) wnew, 0L, True, 8772 VTNonMaskableEvent, (Opaque) NULL); 8773 XtAddEventHandler((Widget) wnew, PropertyChangeMask, False, 8774 HandleBellPropertyChange, (Opaque) NULL); 8775 8776#if HANDLE_STRUCT_NOTIFY 8777#if OPT_TOOLBAR 8778 wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar); 8779 init_Ires(VT100_TB_INFO(menu_height)); 8780#else 8781 /* Flag icon name with "***" on window output when iconified. 8782 * Put in a handler that will tell us when we get Map/Unmap events. 8783 */ 8784 if (resource.zIconBeep) 8785#endif 8786 XtAddEventHandler(my_parent, StructureNotifyMask, False, 8787 HandleStructNotify, (Opaque) 0); 8788#endif /* HANDLE_STRUCT_NOTIFY */ 8789 8790 screen->bellInProgress = False; 8791 8792 set_character_class(screen->charClass); 8793#if OPT_REPORT_CCLASS 8794 if (resource.reportCClass) 8795 report_char_class(wnew); 8796#endif 8797 8798 /* create it, but don't realize it */ 8799 ScrollBarOn(wnew, True); 8800 8801 /* make sure that the resize gravity acceptable */ 8802 if (!GravityIsNorthWest(wnew) && 8803 !GravityIsSouthWest(wnew)) { 8804 char value[80]; 8805 String temp[2]; 8806 Cardinal nparams = 1; 8807 8808 sprintf(value, "%d", wnew->misc.resizeGravity); 8809 temp[0] = value; 8810 temp[1] = 0; 8811 XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError", 8812 "unsupported resizeGravity resource value (%s)", 8813 temp, &nparams); 8814 wnew->misc.resizeGravity = SouthWestGravity; 8815 } 8816#ifndef NO_ACTIVE_ICON 8817 screen->whichVwin = &screen->fullVwin; 8818#endif /* NO_ACTIVE_ICON */ 8819 8820 if (screen->savelines < 0) 8821 screen->savelines = 0; 8822 8823 init_Bres(screen.awaitInput); 8824 8825 wnew->flags = 0; 8826 if (!screen->jumpscroll) 8827 wnew->flags |= SMOOTHSCROLL; 8828 if (wnew->misc.reverseWrap) 8829 wnew->flags |= REVERSEWRAP; 8830 if (wnew->misc.autoWrap) 8831 wnew->flags |= WRAPAROUND; 8832 if (wnew->misc.re_verse != wnew->misc.re_verse0) 8833 wnew->flags |= REVERSE_VIDEO; 8834 if (screen->c132) 8835 wnew->flags |= IN132COLUMNS; 8836 8837 wnew->initflags = wnew->flags; 8838 8839#if OPT_MOD_FKEYS 8840 init_Ires(keyboard.modify_1st.allow_keys); 8841 init_Ires(keyboard.modify_1st.cursor_keys); 8842 init_Ires(keyboard.modify_1st.function_keys); 8843 init_Ires(keyboard.modify_1st.keypad_keys); 8844 init_Ires(keyboard.modify_1st.other_keys); 8845 init_Ires(keyboard.modify_1st.string_keys); 8846 init_Ires(keyboard.format_keys); 8847 wnew->keyboard.modify_now = wnew->keyboard.modify_1st; 8848#endif 8849 8850 init_Ires(misc.appcursorDefault); 8851 if (wnew->misc.appcursorDefault) 8852 wnew->keyboard.flags |= MODE_DECCKM; 8853 8854 init_Ires(misc.appkeypadDefault); 8855 if (wnew->misc.appkeypadDefault) 8856 wnew->keyboard.flags |= MODE_DECKPAM; 8857 8858 initLineData(wnew); 8859#if OPT_WIDE_CHARS 8860 freeFontList(&(request->work.fonts.x11.list_n)); 8861#endif 8862 return; 8863} 8864 8865void 8866releaseCursorGCs(XtermWidget xw) 8867{ 8868 TScreen *screen = TScreenOf(xw); 8869 VTwin *win = WhichVWin(screen); 8870 int n; 8871 8872 for_each_curs_gc(n) { 8873 freeCgs(xw, win, (CgsEnum) n); 8874 } 8875} 8876 8877void 8878releaseWindowGCs(XtermWidget xw, VTwin *win) 8879{ 8880 int n; 8881 8882 for_each_text_gc(n) { 8883 freeCgs(xw, win, (CgsEnum) n); 8884 } 8885} 8886 8887#define TRACE_FREE_LEAK(name) \ 8888 if (name) { \ 8889 TRACE(("freed " #name ": %p\n", (const void *) name)); \ 8890 free((void *) name); \ 8891 name = 0; \ 8892 } 8893 8894#define FREE_LEAK(name) \ 8895 if (name) { \ 8896 free((void *) name); \ 8897 name = 0; \ 8898 } 8899 8900#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 8901static void 8902cleanupInputMethod(XtermWidget xw) 8903{ 8904 TInput *input = lookupTInput(xw, (Widget) xw); 8905 8906 if (input && input->xim) { 8907 XCloseIM(input->xim); 8908 input->xim = 0; 8909 TRACE(("freed screen->xim\n")); 8910 } 8911} 8912#endif 8913 8914static void 8915VTDestroy(Widget w GCC_UNUSED) 8916{ 8917#ifdef NO_LEAKS 8918 XtermWidget xw = (XtermWidget) w; 8919 TScreen *screen = TScreenOf(xw); 8920 Cardinal n, k; 8921 8922 StopBlinking(screen); 8923 8924 if (screen->scrollWidget) { 8925 XtUninstallTranslations(screen->scrollWidget); 8926 XtDestroyWidget(screen->scrollWidget); 8927 } 8928#if OPT_FIFO_LINES 8929 while (screen->saved_fifo > 0) { 8930 deleteScrollback(screen); 8931 } 8932#endif 8933 while (screen->save_title != 0) { 8934 SaveTitle *last = screen->save_title; 8935 screen->save_title = last->next; 8936 free(last->iconName); 8937 free(last->windowName); 8938 free(last); 8939 } 8940 TRACE_FREE_LEAK(xw->misc.active_icon_s); 8941#if OPT_ISO_COLORS 8942 TRACE_FREE_LEAK(screen->cmap_data); 8943 for (n = 0; n < MAXCOLORS; n++) { 8944 TRACE_FREE_LEAK(screen->Acolors[n].resource); 8945 } 8946#endif 8947#if OPT_COLOR_RES 8948 for (n = 0; n < NCOLORS; n++) { 8949 switch (n) { 8950#if OPT_TEK4014 8951 case TEK_BG: 8952 /* FALLTHRU */ 8953 case TEK_FG: 8954 /* FALLTHRU */ 8955 case TEK_CURSOR: 8956 break; 8957#endif 8958 default: 8959 TRACE_FREE_LEAK(screen->Tcolors[n].resource); 8960 break; 8961 } 8962 } 8963#endif 8964 TRACE_FREE_LEAK(screen->save_ptr); 8965 TRACE_FREE_LEAK(screen->saveBuf_data); 8966 TRACE_FREE_LEAK(screen->saveBuf_index); 8967 for (n = 0; n < 2; ++n) { 8968 TRACE_FREE_LEAK(screen->editBuf_data[n]); 8969 TRACE_FREE_LEAK(screen->editBuf_index[n]); 8970 } 8971 TRACE_FREE_LEAK(screen->keyboard_dialect); 8972 TRACE_FREE_LEAK(screen->term_id); 8973#if OPT_WIDE_CHARS 8974#if OPT_LUIT_PROG 8975 TRACE_FREE_LEAK(xw->misc.locale_str); 8976 TRACE_FREE_LEAK(xw->misc.localefilter); 8977#endif 8978#endif 8979 TRACE_FREE_LEAK(xw->misc.T_geometry); 8980 TRACE_FREE_LEAK(xw->misc.geo_metry); 8981 TRACE_FREE_LEAK(xw->screen.term_id); 8982#if OPT_INPUT_METHOD 8983 cleanupInputMethod(xw); 8984 TRACE_FREE_LEAK(xw->misc.f_x); 8985 TRACE_FREE_LEAK(xw->misc.input_method); 8986 TRACE_FREE_LEAK(xw->misc.preedit_type); 8987#endif 8988 releaseCursorGCs(xw); 8989 releaseWindowGCs(xw, &(screen->fullVwin)); 8990#ifndef NO_ACTIVE_ICON 8991 XFreeFont(screen->display, getIconicFont(screen)->fs); 8992 releaseWindowGCs(xw, &(screen->iconVwin)); 8993#endif 8994 XtUninstallTranslations((Widget) xw); 8995#if OPT_TOOLBAR 8996 XtUninstallTranslations((Widget) XtParent(xw)); 8997#endif 8998 XtUninstallTranslations((Widget) SHELL_OF(xw)); 8999 9000 if (screen->hidden_cursor) 9001 XFreeCursor(screen->display, screen->hidden_cursor); 9002 9003 xtermCloseFonts(xw, screen->fnts); 9004#if OPT_WIDE_ATTRS 9005 xtermCloseFonts(xw, screen->ifnts); 9006#endif 9007 noleaks_cachedCgs(xw); 9008 9009 TRACE_FREE_LEAK(screen->selection_targets_8bit); 9010#if OPT_SELECT_REGEX 9011 for (n = 0; n < NSELECTUNITS; ++n) { 9012 if (screen->selectMap[n] == Select_REGEX) { 9013 TRACE_FREE_LEAK(screen->selectExpr[n]); 9014 } 9015 } 9016#endif 9017 9018#if OPT_RENDERFONT 9019 for (n = 0; n < NMENUFONTS; ++n) { 9020 int e; 9021 for (e = 0; e < fMAX; ++e) { 9022 xtermCloseXft(screen, getMyXftFont(xw, e, (int) n)); 9023 } 9024 } 9025 if (screen->renderDraw) 9026 XftDrawDestroy(screen->renderDraw); 9027#endif 9028 9029 /* free things allocated via init_Sres or Init_Sres2 */ 9030#ifndef NO_ACTIVE_ICON 9031 TRACE_FREE_LEAK(screen->icon_fontname); 9032#endif 9033#ifdef ALLOWLOGGING 9034 TRACE_FREE_LEAK(screen->logfile); 9035#endif 9036 TRACE_FREE_LEAK(screen->eight_bit_meta_s); 9037 TRACE_FREE_LEAK(screen->term_id); 9038 TRACE_FREE_LEAK(screen->charClass); 9039 TRACE_FREE_LEAK(screen->answer_back); 9040 TRACE_FREE_LEAK(screen->printer_state.printer_command); 9041 TRACE_FREE_LEAK(screen->keyboard_dialect); 9042 TRACE_FREE_LEAK(screen->disallowedColorOps); 9043 TRACE_FREE_LEAK(screen->disallowedFontOps); 9044 TRACE_FREE_LEAK(screen->disallowedMouseOps); 9045 TRACE_FREE_LEAK(screen->disallowedTcapOps); 9046 TRACE_FREE_LEAK(screen->disallowedWinOps); 9047 TRACE_FREE_LEAK(screen->default_string); 9048 TRACE_FREE_LEAK(screen->eightbit_select_types); 9049 9050#if OPT_WIDE_CHARS 9051 TRACE_FREE_LEAK(screen->utf8_select_types); 9052#endif 9053 9054#if 0 9055 for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) { 9056 TRACE_FREE_LEAK(screen->MenuFontName(n)); 9057 } 9058#endif 9059 9060 TRACE_FREE_LEAK(screen->initial_font); 9061 9062#if OPT_LUIT_PROG 9063 TRACE_FREE_LEAK(xw->misc.locale_str); 9064 TRACE_FREE_LEAK(xw->misc.localefilter); 9065#endif 9066 9067#if OPT_RENDERFONT 9068 TRACE_FREE_LEAK(xw->misc.default_xft.f_n); 9069 TRACE_FREE_LEAK(xw->misc.default_xft.f_w); 9070 TRACE_FREE_LEAK(xw->misc.render_font_s); 9071#endif 9072 9073 TRACE_FREE_LEAK(xw->misc.default_font.f_n); 9074 TRACE_FREE_LEAK(xw->misc.default_font.f_b); 9075 9076#if OPT_WIDE_CHARS 9077 TRACE_FREE_LEAK(xw->misc.default_font.f_w); 9078 TRACE_FREE_LEAK(xw->misc.default_font.f_wb); 9079#endif 9080 9081 freeFontLists(&(xw->work.fonts.x11)); 9082#if OPT_RENDERFONT 9083 freeFontLists(&(xw->work.fonts.xft)); 9084#endif 9085 9086 xtermFontName(NULL); 9087#if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS 9088 TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_n); 9089 TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_b); 9090#if OPT_WIDE_CHARS 9091 TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_w); 9092 TRACE_FREE_LEAK(screen->cacheVTFonts.default_font.f_wb); 9093#endif 9094 freeFontLists(&(screen->cacheVTFonts.fonts.x11)); 9095 for (n = 0; n < NMENUFONTS; ++n) { 9096 for (k = 0; k < fMAX; ++k) { 9097 if (screen->menu_font_names[n][k] != 9098 screen->cacheVTFonts.menu_font_names[n][k]) { 9099 TRACE_FREE_LEAK(screen->menu_font_names[n][k]); 9100 TRACE_FREE_LEAK(screen->cacheVTFonts.menu_font_names[n][k]); 9101 } else { 9102 TRACE_FREE_LEAK(screen->menu_font_names[n][k]); 9103 } 9104 } 9105 } 9106#endif 9107 9108#if OPT_SELECT_REGEX 9109 for (n = 0; n < NSELECTUNITS; ++n) { 9110 FREE_LEAK(screen->selectExpr[n]); 9111 } 9112#endif 9113 9114 if (screen->selection_atoms) 9115 XtFree((void *) (screen->selection_atoms)); 9116 9117 XtFree((void *) (screen->selection_data)); 9118 9119 TRACE_FREE_LEAK(xtermClassRec.core_class.tm_table); 9120 TRACE_FREE_LEAK(xw->keyboard.extra_translations); 9121 TRACE_FREE_LEAK(xw->keyboard.shell_translations); 9122 TRACE_FREE_LEAK(xw->keyboard.xterm_translations); 9123 9124 XtFree((void *) (xw->visInfo)); 9125 9126#if OPT_WIDE_CHARS 9127 FreeTypedBuffer(XChar2b); 9128 FreeTypedBuffer(char); 9129#endif 9130#if OPT_RENDERFONT 9131#if OPT_RENDERWIDE 9132 FreeTypedBuffer(XftCharSpec); 9133#else 9134 FreeTypedBuffer(XftChar8); 9135#endif 9136#endif 9137 9138 TRACE_FREE_LEAK(myState.print_area); 9139 TRACE_FREE_LEAK(myState.string_area); 9140 memset(&myState, 0, sizeof(myState)); 9141 9142#endif /* defined(NO_LEAKS) */ 9143} 9144 9145#ifndef NO_ACTIVE_ICON 9146static void * 9147getProperty(Display *dpy, 9148 Window w, 9149 Atom req_type, 9150 const char *prop_name) 9151{ 9152 Atom property; 9153 Atom actual_return_type; 9154 int actual_format_return = 0; 9155 unsigned long nitems_return = 0; 9156 unsigned long bytes_after_return = 0; 9157 unsigned char *prop_return = 0; 9158 long long_length = 1024; 9159 size_t limit; 9160 char *result = 0; 9161 9162 TRACE(("getProperty %s(%s)\n", prop_name, 9163 req_type ? TraceAtomName(dpy, req_type) : "?")); 9164 property = XInternAtom(dpy, prop_name, False); 9165 9166 if (!xtermGetWinProp(dpy, 9167 w, 9168 property, 9169 0L, 9170 long_length, 9171 req_type, 9172 &actual_return_type, 9173 &actual_format_return, 9174 &nitems_return, 9175 &bytes_after_return, 9176 &prop_return)) { 9177 TRACE((".. Cannot get %s property.\n", prop_name)); 9178 } else if (prop_return != 0) { 9179 9180 if (nitems_return != 0 && 9181 actual_format_return != 0 && 9182 actual_return_type == req_type) { 9183 /* 9184 * Null-terminate the result to make string handling easier. 9185 * The format==8 corresponds to strings, and the number of items 9186 * is the number of characters. 9187 */ 9188 if (actual_format_return == 8) { 9189 limit = nitems_return; 9190 } else { 9191 /* manpage is misleading - X really uses 'long', not 32-bits */ 9192 limit = sizeof(long) * nitems_return; 9193 } 9194 if ((result = malloc(limit + 1)) != 0) { 9195 memcpy(result, prop_return, limit); 9196 result[limit] = '\0'; 9197 } 9198 TRACE(("... result %s\n", result ? ("ok") : "null")); 9199 } 9200 XFree(prop_return); 9201 } else { 9202 TRACE((".. no property returned\n")); 9203 } 9204 return (void *) result; 9205} 9206 9207/* 9208 * Active icons are supported by fvwm. This feature is not supported by 9209 * metacity (gnome) or kwin (kde). Both metacity and kwin support (in 9210 * incompatible ways, e.g., one uses the icon theme as a fallback for window 9211 * decorations but the other does not, etc, ...) an icon as part of the window 9212 * decoration (usually on the upper-left of the window). 9213 * 9214 * In either case, xterm's icon will only be shown in the window decorations if 9215 * xterm does not use the active icon feature. 9216 * 9217 * This function (tries to) determine the window manager's name, so that we can 9218 * provide a useful automatic default for active icons. It is based on reading 9219 * wmctrl, which covers most of EWMH and ICCM. 9220 */ 9221static char * 9222getWindowManagerName(XtermWidget xw) 9223{ 9224 TScreen *screen = TScreenOf(xw); 9225 Display *dpy = screen->display; 9226 Window *sup_window = NULL; 9227 char *result = 0; 9228 9229 TRACE(("getWindowManagerName\n")); 9230#define getWinProp(type, name) \ 9231 (Window *)getProperty(dpy, DefaultRootWindow(dpy), type, name) 9232 if ((sup_window = getWinProp(XA_WINDOW, "_NET_SUPPORTING_WM_CHECK")) == 0) { 9233 sup_window = getWinProp(XA_CARDINAL, "_WIN_SUPPORTING_WM_CHECK"); 9234 } 9235 9236 /* 9237 * If we found the supporting window, get the property containing the 9238 * window manager's name. EWMH defines _NET_WM_NAME, while ICCM defines 9239 * WM_CLASS. There is no standard for the names stored there; 9240 * conventionally it is mixed case. In practice, the former is more often 9241 * set; the latter is not given (or is a lowercased version of the former). 9242 */ 9243 if (sup_window != 0) { 9244#define getStringProp(type,name) \ 9245 (char *)getProperty(dpy, *sup_window, type, name) 9246 if ((result = getStringProp(XA_UTF8_STRING(dpy), "_NET_WM_NAME")) == 0 9247 && (result = getStringProp(XA_STRING, "_NET_WM_NAME")) == 0 9248 && (result = getStringProp(XA_STRING, "WM_CLASS")) == 0) { 9249 TRACE(("... window manager does not tell its name\n")); 9250 } 9251 free(sup_window); 9252 } else { 9253 TRACE(("... Cannot get window manager info properties\n")); 9254 } 9255 if (result == 0) 9256 result = x_strdup("unknown"); 9257 TRACE(("... window manager name is %s\n", result)); 9258 return result; 9259} 9260#endif 9261 9262/*ARGSUSED*/ 9263static void 9264VTRealize(Widget w, 9265 XtValueMask * valuemask, 9266 XSetWindowAttributes * values) 9267{ 9268 XtermWidget xw = (XtermWidget) w; 9269 TScreen *screen = TScreenOf(xw); 9270 9271 const VTFontNames *myfont; 9272 struct Xinerama_geometry pos; 9273 int pr; 9274 Atom pid_atom; 9275 int i; 9276 9277 TRACE(("VTRealize {{\n")); 9278 9279#if OPT_TOOLBAR 9280 /* 9281 * Layout for the toolbar confuses the Shell widget. Remind it that we 9282 * would like to be iconified if the corresponding resource was set. 9283 */ 9284 if (XtIsRealized(toplevel)) { 9285 Boolean iconic = 0; 9286 9287 XtVaGetValues(toplevel, 9288 XtNiconic, &iconic, 9289 (XtPointer) 0); 9290 9291 if (iconic) { 9292 XIconifyWindow(XtDisplay(toplevel), 9293 XtWindow(toplevel), 9294 DefaultScreen(XtDisplay(toplevel))); 9295 } 9296 } 9297#endif 9298 9299 TabReset(xw->tabs); 9300 9301 if (screen->menu_font_number == fontMenu_default) { 9302 myfont = defaultVTFontNames(xw); 9303 } else { 9304 myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number)); 9305 } 9306 memset(screen->fnts, 0, sizeof(screen->fnts)); 9307 9308 if (!xtermLoadFont(xw, 9309 myfont, 9310 False, 9311 screen->menu_font_number)) { 9312 if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) { 9313 char *use_font = x_strdup(DEFFONT); 9314 xtermWarning("unable to open font \"%s\", trying \"%s\"....\n", 9315 myfont->f_n, use_font); 9316 (void) xtermLoadFont(xw, 9317 xtermFontName(use_font), 9318 False, 9319 screen->menu_font_number); 9320 screen->MenuFontName(screen->menu_font_number) = use_font; 9321 } 9322 } 9323 9324 /* really screwed if we couldn't open default font */ 9325 if (!getNormalFont(screen, fNorm)->fs) { 9326 xtermWarning("unable to locate a suitable font\n"); 9327 Exit(1); 9328 } 9329#if OPT_WIDE_CHARS 9330 if (screen->utf8_mode) { 9331 TRACE(("check if this is a wide font, if not try again\n")); 9332 if (xtermLoadWideFonts(xw, False)) { 9333 SetVTFont(xw, screen->menu_font_number, True, NULL); 9334 /* we will not be able to switch to ISO-8859-1 */ 9335 if (!screen->mergedVTFonts) { 9336 screen->utf8_fonts = uAlways; 9337 update_font_utf8_fonts(); 9338 } 9339 } 9340 } 9341#endif 9342 9343 /* making cursor */ 9344 if (!screen->pointer_cursor) { 9345 screen->pointer_cursor = 9346 make_colored_cursor(XC_xterm, 9347 T_COLOR(screen, MOUSE_FG), 9348 T_COLOR(screen, MOUSE_BG)); 9349 } else { 9350 recolor_cursor(screen, 9351 screen->pointer_cursor, 9352 T_COLOR(screen, MOUSE_FG), 9353 T_COLOR(screen, MOUSE_BG)); 9354 } 9355 9356 /* set defaults */ 9357 pos.x = 1; 9358 pos.y = 1; 9359 pos.w = 80; 9360 pos.h = 24; 9361 9362 TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry))); 9363 pr = XParseXineramaGeometry(screen->display, xw->misc.geo_metry, &pos); 9364 TRACE(("... position %d,%d size %dx%d\n", pos.y, pos.x, pos.h, pos.w)); 9365 9366 set_max_col(screen, (int) (pos.w - 1)); /* units in character cells */ 9367 set_max_row(screen, (int) (pos.h - 1)); /* units in character cells */ 9368 xtermUpdateFontInfo(xw, False); 9369 9370 pos.w = screen->fullVwin.fullwidth; 9371 pos.h = screen->fullVwin.fullheight; 9372 9373 TRACE(("... border widget %d parent %d shell %d\n", 9374 BorderWidth(xw), 9375 BorderWidth(XtParent(xw)), 9376 BorderWidth(SHELL_OF(xw)))); 9377 9378 if ((pr & XValue) && (XNegative & pr)) { 9379 pos.x = (Position) (pos.x + (pos.scr_w 9380 - (int) pos.w 9381 - (BorderWidth(XtParent(xw)) * 2))); 9382 } 9383 if ((pr & YValue) && (YNegative & pr)) { 9384 pos.y = (Position) (pos.y + (pos.scr_h 9385 - (int) pos.h 9386 - (BorderWidth(XtParent(xw)) * 2))); 9387 } 9388 pos.x = (Position) (pos.x + pos.scr_x); 9389 pos.y = (Position) (pos.y + pos.scr_y); 9390 9391 /* set up size hints for window manager; min 1 char by 1 char */ 9392 getXtermSizeHints(xw); 9393 xtermSizeHints(xw, (xw->misc.scrollbar 9394 ? (screen->scrollWidget->core.width 9395 + BorderWidth(screen->scrollWidget)) 9396 : 0)); 9397 9398 xw->hints.x = pos.x; 9399 xw->hints.y = pos.y; 9400#if OPT_MAXIMIZE 9401 /* assure single-increment resize for fullscreen */ 9402 if (term->work.ewmh[0].mode) { 9403 xw->hints.width_inc = 1; 9404 xw->hints.height_inc = 1; 9405 } 9406#endif 9407 if ((XValue & pr) || (YValue & pr)) { 9408 xw->hints.flags |= USSize | USPosition; 9409 xw->hints.flags |= PWinGravity; 9410 switch (pr & (XNegative | YNegative)) { 9411 case 0: 9412 xw->hints.win_gravity = NorthWestGravity; 9413 break; 9414 case XNegative: 9415 xw->hints.win_gravity = NorthEastGravity; 9416 break; 9417 case YNegative: 9418 xw->hints.win_gravity = SouthWestGravity; 9419 break; 9420 default: 9421 xw->hints.win_gravity = SouthEastGravity; 9422 break; 9423 } 9424 } else { 9425 /* set a default size, but do *not* set position */ 9426 xw->hints.flags |= PSize; 9427 } 9428 xw->hints.height = xw->hints.base_height 9429 + xw->hints.height_inc * MaxRows(screen); 9430 xw->hints.width = xw->hints.base_width 9431 + xw->hints.width_inc * MaxCols(screen); 9432 9433 if ((WidthValue & pr) || (HeightValue & pr)) 9434 xw->hints.flags |= USSize; 9435 else 9436 xw->hints.flags |= PSize; 9437 9438 /* 9439 * Note that the size-hints are for the shell, while the resize-request 9440 * is for the vt100 widget. They are not the same size. 9441 */ 9442 (void) REQ_RESIZE((Widget) xw, 9443 (Dimension) pos.w, (Dimension) pos.h, 9444 &xw->core.width, &xw->core.height); 9445 9446 /* XXX This is bogus. We are parsing geometries too late. This 9447 * is information that the shell widget ought to have before we get 9448 * realized, so that it can do the right thing. 9449 */ 9450 if (xw->hints.flags & USPosition) 9451 XMoveWindow(XtDisplay(xw), VShellWindow(xw), 9452 xw->hints.x, xw->hints.y); 9453 9454 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 9455 TRACE_HINTS(&xw->hints); 9456 XSetWMNormalHints(XtDisplay(xw), VShellWindow(xw), &xw->hints); 9457 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 9458 TRACE_WM_HINTS(xw); 9459 9460 if ((pid_atom = XInternAtom(XtDisplay(xw), "_NET_WM_PID", False)) != None) { 9461 /* XChangeProperty format 32 really is "long" */ 9462 unsigned long pid_l = (unsigned long) getpid(); 9463 TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l)); 9464 XChangeProperty(XtDisplay(xw), VShellWindow(xw), 9465 pid_atom, XA_CARDINAL, 32, PropModeReplace, 9466 (unsigned char *) &pid_l, 1); 9467 } 9468 9469 XFlush(XtDisplay(xw)); /* get it out to window manager */ 9470 9471 /* use ForgetGravity instead of SouthWestGravity because translating 9472 the Expose events for ConfigureNotifys is too hard */ 9473 values->bit_gravity = (GravityIsNorthWest(xw) 9474 ? NorthWestGravity 9475 : ForgetGravity); 9476 screen->fullVwin.window = XtWindow(xw) = 9477 XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)), 9478 xw->core.x, xw->core.y, 9479 xw->core.width, xw->core.height, BorderWidth(xw), 9480 (int) xw->core.depth, 9481 InputOutput, CopyFromParent, 9482 *valuemask | CWBitGravity, values); 9483#if OPT_DOUBLE_BUFFER 9484 screen->fullVwin.drawable = screen->fullVwin.window; 9485 9486 { 9487 Window win = screen->fullVwin.window; 9488 Drawable d; 9489 int major, minor; 9490 if (!XdbeQueryExtension(XtDisplay(xw), &major, &minor)) { 9491 fprintf(stderr, "XdbeQueryExtension returned zero!\n"); 9492 exit(3); 9493 } 9494 d = XdbeAllocateBackBufferName(XtDisplay(xw), win, XdbeCopied); 9495 if (d == None) { 9496 fprintf(stderr, "Couldn't allocate a back buffer!\n"); 9497 exit(3); 9498 } 9499 screen->fullVwin.drawable = d; 9500 screen->needSwap = 1; 9501 } 9502#endif /* OPT_DOUBLE_BUFFER */ 9503 screen->event_mask = values->event_mask; 9504 9505#ifndef NO_ACTIVE_ICON 9506 /* 9507 * Normally, the font-number for icon fonts does not correspond with any of 9508 * the menu-selectable fonts. If we cannot load the font given for the 9509 * iconFont resource, try with font1 aka "Unreadable". 9510 */ 9511 screen->icon_fontnum = -1; 9512 if (getIconicFont(screen)->fs == 0) { 9513 getIconicFont(screen)->fs = 9514 XLoadQueryFont(screen->display, 9515 screen->MenuFontName(fontMenu_font1)); 9516 TRACE(("%susing font1 '%s' as iconFont\n", 9517 (getIconicFont(screen)->fs 9518 ? "" 9519 : "NOT "), 9520 screen->MenuFontName(fontMenu_font1))); 9521 } 9522#if OPT_RENDERFONT 9523 /* 9524 * If we still have no result from iconFont resource (perhaps because fonts 9525 * are missing) but are using Xft, try to use that instead. We prefer 9526 * bitmap fonts in any case, since scaled fonts are usually less readable, 9527 * particularly at small sizes. 9528 */ 9529 if (UsingRenderFont(xw) 9530 && getIconicFont(screen)->fs == 0) { 9531 screen->icon_fontnum = fontMenu_default; 9532 getIconicFont(screen)->fs = getNormalFont(screen, fNorm)->fs; /* need for next-if */ 9533 TRACE(("using TrueType font as iconFont\n")); 9534 } 9535#endif 9536 if ((xw->work.active_icon == eiDefault) && getIconicFont(screen)->fs) { 9537 char *wm_name = getWindowManagerName(xw); 9538 if (x_strncasecmp(wm_name, "fvwm", 4) && 9539 x_strncasecmp(wm_name, "window maker", 12)) 9540 xw->work.active_icon = eiFalse; 9541 free(wm_name); 9542 } 9543 if (xw->work.active_icon && getIconicFont(screen)->fs) { 9544 int iconX = 0, iconY = 0; 9545 Widget shell = SHELL_OF(xw); 9546 VTwin *win = &(screen->iconVwin); 9547 int save_fontnum = screen->menu_font_number; 9548 9549 TRACE(("Initializing active-icon %d\n", screen->icon_fontnum)); 9550 screen->menu_font_number = screen->icon_fontnum; 9551 XtVaGetValues(shell, 9552 XtNiconX, &iconX, 9553 XtNiconY, &iconY, 9554 (XtPointer) 0); 9555 xtermComputeFontInfo(xw, &(screen->iconVwin), 9556 getIconicFont(screen)->fs, 0); 9557 screen->menu_font_number = save_fontnum; 9558 9559 /* since only one client is permitted to select for Button 9560 * events, we have to let the window manager get 'em... 9561 */ 9562 values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask); 9563 values->border_pixel = xw->misc.icon_border_pixel; 9564 9565 screen->iconVwin.window = 9566 XCreateWindow(XtDisplay(xw), 9567 RootWindowOfScreen(XtScreen(shell)), 9568 iconX, iconY, 9569 screen->iconVwin.fullwidth, 9570 screen->iconVwin.fullheight, 9571 xw->misc.icon_border_width, 9572 (int) xw->core.depth, 9573 InputOutput, CopyFromParent, 9574 *valuemask | CWBitGravity | CWBorderPixel, 9575 values); 9576#if OPT_DOUBLE_BUFFER 9577 screen->iconVwin.drawable = screen->iconVwin.window; 9578#endif 9579 XtVaSetValues(shell, 9580 XtNiconWindow, screen->iconVwin.window, 9581 (XtPointer) 0); 9582 XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w); 9583 9584 setCgsFont(xw, win, gcNorm, getIconicFont(screen)); 9585 setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG)); 9586 setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG)); 9587 9588 copyCgs(xw, win, gcBold, gcNorm); 9589 9590 setCgsFont(xw, win, gcNormReverse, getIconicFont(screen)); 9591 setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG)); 9592 setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG)); 9593 9594 copyCgs(xw, win, gcBoldReverse, gcNormReverse); 9595 9596#if OPT_TOOLBAR 9597 /* 9598 * Toolbar is initialized before we get here. Enable the menu item 9599 * and set it properly. 9600 */ 9601 SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, True); 9602 update_activeicon(); 9603#endif 9604 } else { 9605 TRACE(("Disabled active-icon\n")); 9606 xw->work.active_icon = eiFalse; 9607 } 9608#endif /* NO_ACTIVE_ICON */ 9609 9610#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 9611 VTInitI18N(xw); 9612#endif 9613#if OPT_NUM_LOCK 9614 VTInitModifiers(xw); 9615#if OPT_EXTRA_PASTE 9616 if (xw->keyboard.extra_translations) { 9617 XtOverrideTranslations((Widget) xw, 9618 XtParseTranslationTable(xw->keyboard.extra_translations)); 9619 } 9620#endif 9621#endif 9622 9623 set_cursor_gcs(xw); 9624 9625 /* Reset variables used by ANSI emulation. */ 9626 9627 resetCharsets(screen); 9628 9629 XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor); 9630 9631 set_cur_col(screen, 0); 9632 set_cur_row(screen, 0); 9633 set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1); 9634 set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1); 9635 reset_margins(screen); 9636 9637 memset(screen->sc, 0, sizeof(screen->sc)); 9638 9639 /* Mark screen buffer as unallocated. We wait until the run loop so 9640 that the child process does not fork and exec with all the dynamic 9641 memory it will never use. If we were to do it here, the 9642 swap space for new process would be huge for huge savelines. */ 9643#if OPT_TEK4014 9644 if (!tekWidget) /* if not called after fork */ 9645#endif 9646 { 9647 screen->visbuf = NULL; 9648 screen->saveBuf_index = NULL; 9649 } 9650 9651 ResetWrap(screen); 9652 screen->scrolls = screen->incopy = 0; 9653 xtermSetCursorBox(screen); 9654 9655 screen->savedlines = 0; 9656 9657 for (i = 0; i < 2; ++i) { 9658 screen->whichBuf = !screen->whichBuf; 9659 CursorSave(xw); 9660 } 9661 9662#ifndef NO_ACTIVE_ICON 9663 if (!xw->work.active_icon) 9664#endif 9665 xtermLoadIcon(xw); 9666 9667 /* 9668 * Do this last, since it may change the layout via a resize. 9669 */ 9670 if (xw->misc.scrollbar) { 9671 screen->fullVwin.sb_info.width = 0; 9672 ScrollBarOn(xw, False); 9673 } 9674 9675 xtermSetWinSize(xw); 9676 TRACE(("}} VTRealize\n")); 9677} 9678 9679#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 9680 9681/* limit this feature to recent XFree86 since X11R6.x core dumps */ 9682#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING) 9683#define USE_XIM_INSTANTIATE_CB 9684 9685static void 9686xim_instantiate_cb(Display *display, 9687 XPointer client_data GCC_UNUSED, 9688 XPointer call_data GCC_UNUSED) 9689{ 9690 TRACE(("xim_instantiate_cb client=%p, call=%p\n", client_data, call_data)); 9691 9692 if (display == XtDisplay(term)) { 9693 VTInitI18N(term); 9694 } 9695} 9696 9697static void 9698xim_destroy_cb(XIM im GCC_UNUSED, 9699 XPointer client_data GCC_UNUSED, 9700 XPointer call_data GCC_UNUSED) 9701{ 9702 XtermWidget xw = term; 9703 TInput *input = lookupTInput(xw, (Widget) xw); 9704 9705 TRACE(("xim_destroy_cb im=%lx, client=%p, call=%p\n", 9706 (long) im, client_data, call_data)); 9707 if (input) 9708 input->xic = NULL; 9709 XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL, 9710 xim_instantiate_cb, NULL); 9711} 9712#endif /* X11R6+ */ 9713 9714static Boolean 9715xim_create_fs(XtermWidget xw) 9716{ 9717 XFontStruct **fonts; 9718 char **font_name_list; 9719 char **missing_charset_list; 9720 char *def_string; 9721 int missing_charset_count; 9722 unsigned i, j; 9723 9724 if (xw->work.xim_fs == 0) { 9725 xw->work.xim_fs = XCreateFontSet(XtDisplay(xw), 9726 xw->misc.f_x, 9727 &missing_charset_list, 9728 &missing_charset_count, 9729 &def_string); 9730 if (xw->work.xim_fs == NULL) { 9731 xtermWarning("Preparation of font set " 9732 "\"%s\" for XIM failed.\n", xw->misc.f_x); 9733 xw->work.xim_fs = XCreateFontSet(XtDisplay(xw), 9734 DEFXIMFONT, 9735 &missing_charset_list, 9736 &missing_charset_count, 9737 &def_string); 9738 } 9739 } 9740 if (xw->work.xim_fs == NULL) { 9741 xtermWarning("Preparation of default font set " 9742 "\"%s\" for XIM failed.\n", DEFXIMFONT); 9743 cleanupInputMethod(xw); 9744 xw->work.cannot_im = True; 9745 } else { 9746 (void) XExtentsOfFontSet(xw->work.xim_fs); 9747 j = (unsigned) XFontsOfFontSet(xw->work.xim_fs, &fonts, &font_name_list); 9748 for (i = 0, xw->work.xim_fs_ascent = 0; i < j; i++) { 9749 if (xw->work.xim_fs_ascent < (*fonts)->ascent) 9750 xw->work.xim_fs_ascent = (*fonts)->ascent; 9751 } 9752 } 9753 return (Boolean) !(xw->work.cannot_im); 9754} 9755 9756static void 9757xim_create_xic(XtermWidget xw, Widget theInput) 9758{ 9759 Display *myDisplay = XtDisplay(theInput); 9760 Window myWindow = XtWindow(theInput); 9761 unsigned i, j; 9762 char *p = NULL, *s, *t, *ns, *end, buf[32]; 9763 XIMStyles *xim_styles; 9764 XIMStyle input_style = 0; 9765 Bool found; 9766 static struct { 9767 const char *name; 9768 unsigned long code; 9769 } known_style[] = { 9770 { 9771 "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing) 9772 }, 9773 { 9774 "OffTheSpot", (XIMPreeditArea | XIMStatusArea) 9775 }, 9776 { 9777 "Root", (XIMPreeditNothing | XIMStatusNothing) 9778 }, 9779 }; 9780 TInput *input = lookupTInput(xw, theInput); 9781 9782 if (xw->work.cannot_im) { 9783 return; 9784 } 9785 9786 if (input == 0) { 9787 for (i = 0; i < NINPUTWIDGETS; ++i) { 9788 if (xw->work.inputs[i].w == 0) { 9789 input = xw->work.inputs + i; 9790 input->w = theInput; 9791 break; 9792 } 9793 } 9794 } 9795 9796 if (input == 0) { 9797 xtermWarning("attempted to add too many input widgets\n"); 9798 return; 9799 } 9800 9801 TRACE(("xim_real_init\n")); 9802 9803 if (IsEmpty(xw->misc.input_method)) { 9804 if ((p = XSetLocaleModifiers("")) != NULL && *p) { 9805 input->xim = XOpenIM(myDisplay, NULL, NULL, NULL); 9806 } 9807 } else { 9808 s = xw->misc.input_method; 9809 i = 5 + (unsigned) strlen(s); 9810 9811 t = (char *) MyStackAlloc(i, buf); 9812 if (t == NULL) { 9813 SysError(ERROR_VINIT); 9814 } else { 9815 9816 for (ns = s; ns && *s;) { 9817 while (*s && isspace(CharOf(*s))) 9818 s++; 9819 if (!*s) 9820 break; 9821 if ((ns = end = strchr(s, ',')) == 0) 9822 end = s + strlen(s); 9823 while ((end != s) && isspace(CharOf(end[-1]))) 9824 end--; 9825 9826 if (end != s) { 9827 strcpy(t, "@im="); 9828 strncat(t, s, (size_t) (end - s)); 9829 9830 if ((p = XSetLocaleModifiers(t)) != 0 && *p 9831 && (input->xim = XOpenIM(myDisplay, 9832 NULL, 9833 NULL, 9834 NULL)) != 0) { 9835 break; 9836 } 9837 9838 } 9839 s = ns + 1; 9840 } 9841 MyStackFree(t, buf); 9842 } 9843 } 9844 9845 if (input->xim == NULL 9846 && (p = XSetLocaleModifiers("@im=none")) != NULL 9847 && *p) { 9848 input->xim = XOpenIM(myDisplay, NULL, NULL, NULL); 9849 } 9850 9851 if (!input->xim) { 9852 xtermWarning("Failed to open input method\n"); 9853 return; 9854 } 9855 TRACE(("VTInitI18N opened input method:%s\n", NonNull(p))); 9856 9857 if (XGetIMValues(input->xim, XNQueryInputStyle, &xim_styles, (void *) 0) 9858 || !xim_styles 9859 || !xim_styles->count_styles) { 9860 xtermWarning("input method doesn't support any style\n"); 9861 cleanupInputMethod(xw); 9862 xw->work.cannot_im = True; 9863 return; 9864 } 9865 9866 found = False; 9867 for (s = xw->misc.preedit_type; s && !found;) { 9868 while (*s && isspace(CharOf(*s))) 9869 s++; 9870 if (!*s) 9871 break; 9872 if ((ns = end = strchr(s, ',')) != 0) 9873 ns++; 9874 else 9875 end = s + strlen(s); 9876 while ((end != s) && isspace(CharOf(end[-1]))) 9877 end--; 9878 9879 if (end != s) { /* just in case we have a spurious comma */ 9880 TRACE(("looking for style '%.*s'\n", (int) (end - s), s)); 9881 for (i = 0; i < XtNumber(known_style); i++) { 9882 if ((int) strlen(known_style[i].name) == (end - s) 9883 && !strncmp(s, known_style[i].name, (size_t) (end - s))) { 9884 input_style = known_style[i].code; 9885 for (j = 0; j < xim_styles->count_styles; j++) { 9886 if (input_style == xim_styles->supported_styles[j]) { 9887 found = True; 9888 break; 9889 } 9890 } 9891 if (found) 9892 break; 9893 } 9894 } 9895 } 9896 9897 s = ns; 9898 } 9899 XFree(xim_styles); 9900 9901 if (!found) { 9902 xtermWarning("input method doesn't support my preedit type (%s)\n", 9903 xw->misc.preedit_type); 9904 cleanupInputMethod(xw); 9905 xw->work.cannot_im = True; 9906 return; 9907 } 9908 9909 /* 9910 * Check for styles we do not yet support. 9911 */ 9912 TRACE(("input_style %#lx\n", input_style)); 9913 if (input_style == (XIMPreeditArea | XIMStatusArea)) { 9914 xtermWarning("This program doesn't support the 'OffTheSpot' preedit type\n"); 9915 cleanupInputMethod(xw); 9916 xw->work.cannot_im = True; 9917 return; 9918 } 9919 9920 /* 9921 * For XIMPreeditPosition (or OverTheSpot), XIM client has to 9922 * prepare a font. 9923 * The font has to be locale-dependent XFontSet, whereas 9924 * XTerm use Unicode font. This leads a problem that the 9925 * same font cannot be used for XIM preedit. 9926 */ 9927 if (input_style != (XIMPreeditNothing | XIMStatusNothing)) { 9928 XVaNestedList p_list; 9929 XPoint spot = 9930 {0, 0}; 9931 9932 if (xim_create_fs(xw)) { 9933 p_list = XVaCreateNestedList(0, 9934 XNSpotLocation, &spot, 9935 XNFontSet, xw->work.xim_fs, 9936 (void *) 0); 9937 input->xic = XCreateIC(input->xim, 9938 XNInputStyle, input_style, 9939 XNClientWindow, myWindow, 9940 XNFocusWindow, myWindow, 9941 XNPreeditAttributes, p_list, 9942 (void *) 0); 9943 } 9944 } else { 9945 input->xic = XCreateIC(input->xim, XNInputStyle, input_style, 9946 XNClientWindow, myWindow, 9947 XNFocusWindow, myWindow, 9948 (void *) 0); 9949 } 9950 9951 if (!input->xic) { 9952 xtermWarning("Failed to create input context\n"); 9953 cleanupInputMethod(xw); 9954 } 9955#if defined(USE_XIM_INSTANTIATE_CB) 9956 else { 9957 XIMCallback destroy_cb; 9958 9959 destroy_cb.callback = xim_destroy_cb; 9960 destroy_cb.client_data = NULL; 9961 if (XSetIMValues(input->xim, 9962 XNDestroyCallback, 9963 &destroy_cb, 9964 (void *) 0)) { 9965 xtermWarning("Could not set destroy callback to IM\n"); 9966 } 9967 } 9968#endif 9969 9970 return; 9971} 9972 9973static void 9974xim_real_init(XtermWidget xw) 9975{ 9976 xim_create_xic(xw, (Widget) xw); 9977} 9978 9979static void 9980VTInitI18N(XtermWidget xw) 9981{ 9982 if (xw->misc.open_im) { 9983 xim_real_init(xw); 9984 9985#if defined(USE_XIM_INSTANTIATE_CB) 9986 if (lookupTInput(xw, (Widget) xw) == NULL 9987 && !xw->work.cannot_im 9988 && xw->misc.retry_im-- > 0) { 9989 sleep(3); 9990 XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL, 9991 xim_instantiate_cb, NULL); 9992 } 9993#endif 9994 } 9995} 9996 9997TInput * 9998lookupTInput(XtermWidget xw, Widget w) 9999{ 10000 TInput *result = 0; 10001 unsigned n; 10002 10003 for (n = 0; n < NINPUTWIDGETS; ++n) { 10004 if (xw->work.inputs[n].w == w) { 10005 result = xw->work.inputs + n; 10006 break; 10007 } 10008 } 10009 10010 return result; 10011} 10012#endif /* OPT_I18N_SUPPORT && OPT_INPUT_METHOD */ 10013 10014static void 10015set_cursor_outline_gc(XtermWidget xw, 10016 Bool filled, 10017 Pixel fg, 10018 Pixel bg, 10019 Pixel cc) 10020{ 10021 TScreen *screen = TScreenOf(xw); 10022 VTwin *win = WhichVWin(screen); 10023 CgsEnum cgsId = gcVTcursOutline; 10024 10025 if (cc == bg) 10026 cc = fg; 10027 10028 if (filled) { 10029 setCgsFore(xw, win, cgsId, bg); 10030 setCgsBack(xw, win, cgsId, cc); 10031 } else { 10032 setCgsFore(xw, win, cgsId, cc); 10033 setCgsBack(xw, win, cgsId, bg); 10034 } 10035} 10036 10037static Boolean 10038VTSetValues(Widget cur, 10039 Widget request GCC_UNUSED, 10040 Widget wnew, 10041 ArgList args GCC_UNUSED, 10042 Cardinal *num_args GCC_UNUSED) 10043{ 10044 XtermWidget curvt = (XtermWidget) cur; 10045 XtermWidget newvt = (XtermWidget) wnew; 10046 Boolean refresh_needed = False; 10047 Boolean fonts_redone = False; 10048 10049 if ((T_COLOR(TScreenOf(curvt), TEXT_BG) != 10050 T_COLOR(TScreenOf(newvt), TEXT_BG)) || 10051 (T_COLOR(TScreenOf(curvt), TEXT_FG) != 10052 T_COLOR(TScreenOf(newvt), TEXT_FG)) || 10053 (TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) != 10054 TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) || 10055 strcmp(DefaultFontN(curvt), DefaultFontN(newvt))) { 10056 if (strcmp(DefaultFontN(curvt), DefaultFontN(newvt))) { 10057 TScreenOf(newvt)->MenuFontName(fontMenu_default) = DefaultFontN(newvt); 10058 } 10059 if (xtermLoadFont(newvt, 10060 xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)), 10061 True, TScreenOf(newvt)->menu_font_number)) { 10062 /* resizing does the redisplay, so don't ask for it here */ 10063 refresh_needed = True; 10064 fonts_redone = True; 10065 } else if (strcmp(DefaultFontN(curvt), DefaultFontN(newvt))) { 10066 TScreenOf(newvt)->MenuFontName(fontMenu_default) = DefaultFontN(curvt); 10067 } 10068 } 10069 if (!fonts_redone 10070 && (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) != 10071 T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) { 10072 if (set_cursor_gcs(newvt)) 10073 refresh_needed = True; 10074 } 10075 if (curvt->misc.re_verse != newvt->misc.re_verse) { 10076 newvt->flags ^= REVERSE_VIDEO; 10077 ReverseVideo(newvt); 10078 /* ReverseVideo toggles */ 10079 newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse); 10080 refresh_needed = True; 10081 } 10082 if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) != 10083 T_COLOR(TScreenOf(newvt), MOUSE_FG)) || 10084 (T_COLOR(TScreenOf(curvt), MOUSE_BG) != 10085 T_COLOR(TScreenOf(newvt), MOUSE_BG))) { 10086 recolor_cursor(TScreenOf(newvt), 10087 TScreenOf(newvt)->pointer_cursor, 10088 T_COLOR(TScreenOf(newvt), MOUSE_FG), 10089 T_COLOR(TScreenOf(newvt), MOUSE_BG)); 10090 refresh_needed = True; 10091 } 10092 if (curvt->misc.scrollbar != newvt->misc.scrollbar) { 10093 ToggleScrollBar(newvt); 10094 } 10095 10096 return refresh_needed; 10097} 10098 10099/* 10100 * Given a font-slot and information about selection/reverse, find the 10101 * corresponding cached-GC slot. 10102 */ 10103static int 10104reverseCgs(XtermWidget xw, unsigned attr_flags, Bool hilite, int font) 10105{ 10106 TScreen *screen = TScreenOf(xw); 10107 CgsEnum result = gcMAX; 10108 10109 if (ReverseOrHilite(screen, attr_flags, hilite)) { 10110 switch (font) { 10111 case fNorm: 10112 result = gcNormReverse; 10113 break; 10114 case fBold: 10115 result = gcBoldReverse; 10116 break; 10117#if OPT_WIDE_ATTRS || OPT_RENDERWIDE 10118 case fItal: 10119 result = gcNormReverse; /* FIXME */ 10120 break; 10121#endif 10122#if OPT_WIDE_CHARS 10123 case fWide: 10124 result = gcWideReverse; 10125 break; 10126 case fWBold: 10127 result = gcWBoldReverse; 10128 break; 10129 case fWItal: 10130 result = gcWideReverse; /* FIXME */ 10131 break; 10132#endif 10133 } 10134 } else { 10135 switch (font) { 10136 case fNorm: 10137 result = gcNorm; 10138 break; 10139 case fBold: 10140 result = gcBold; 10141 break; 10142#if OPT_WIDE_ATTRS || OPT_RENDERWIDE 10143 case fItal: 10144 result = gcNorm; /* FIXME */ 10145 break; 10146#endif 10147#if OPT_WIDE_CHARS 10148 case fWide: 10149 result = gcWide; 10150 break; 10151 case fWBold: 10152 result = gcWBold; 10153 break; 10154 case fWItal: 10155 result = gcWide; /* FIXME */ 10156 break; 10157#endif 10158 } 10159 } 10160 return result; 10161} 10162 10163#define setGC(code) set_at = __LINE__, currentCgs = code 10164 10165#define OutsideSelection(screen,srow,scol) \ 10166 ((srow) > (screen)->endH.row || \ 10167 ((srow) == (screen)->endH.row && \ 10168 (scol) >= (screen)->endH.col) || \ 10169 (srow) < (screen)->startH.row || \ 10170 ((srow) == (screen)->startH.row && \ 10171 (scol) < (screen)->startH.col)) 10172 10173/* 10174 * Shows cursor at new cursor position in screen. 10175 */ 10176void 10177ShowCursor(void) 10178{ 10179 XtermWidget xw = term; 10180 TScreen *screen = TScreenOf(xw); 10181 IChar base; 10182 unsigned flags; 10183 CellColor fg_bg = 0; 10184 GC currentGC; 10185 GC outlineGC; 10186 CgsEnum currentCgs = gcMAX; 10187 VTwin *currentWin = WhichVWin(screen); 10188 int set_at; 10189 Bool in_selection; 10190 Bool reversed; 10191 Bool filled; 10192 Pixel fg_pix; 10193 Pixel bg_pix; 10194 Pixel tmp; 10195#if OPT_HIGHLIGHT_COLOR 10196 Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG); 10197 Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG); 10198 Boolean use_selbg; 10199 Boolean use_selfg; 10200#endif 10201#if OPT_WIDE_CHARS 10202 int my_col = 0; 10203#endif 10204 int cursor_col; 10205 CLineData *ld = 0; 10206 10207 if (screen->cursor_state == BLINKED_OFF) 10208 return; 10209 10210 if (screen->eventMode != NORMAL) 10211 return; 10212 10213 if (INX2ROW(screen, screen->cur_row) > screen->max_row) 10214 return; 10215 10216 screen->cursorp.row = screen->cur_row; 10217 cursor_col = screen->cursorp.col = screen->cur_col; 10218 screen->cursor_moved = False; 10219 10220#ifndef NO_ACTIVE_ICON 10221 if (IsIcon(screen)) { 10222 screen->cursor_state = ON; 10223 return; 10224 } 10225#endif /* NO_ACTIVE_ICON */ 10226 10227 ld = getLineData(screen, screen->cur_row); 10228 10229 base = ld->charData[cursor_col]; 10230 flags = ld->attribs[cursor_col]; 10231 10232 if_OPT_WIDE_CHARS(screen, { 10233 if (base == HIDDEN_CHAR && cursor_col > 0) { 10234 /* if cursor points to non-initial part of wide character, 10235 * back it up 10236 */ 10237 --cursor_col; 10238 base = ld->charData[cursor_col]; 10239 } 10240 my_col = cursor_col; 10241 if (base == 0) 10242 base = ' '; 10243 if (isWide((int) base)) 10244 my_col += 1; 10245 }); 10246 10247 if (base == 0) { 10248 base = ' '; 10249 } 10250#if OPT_ISO_COLORS 10251#ifdef EXP_BOGUS_FG 10252 /* 10253 * If the cursor happens to be on blanks, and we have not set both 10254 * foreground and background color, do not treat it as a colored cell. 10255 */ 10256 if (base == ' ') { 10257 if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) { 10258 TRACE(("ShowCursor - do not treat as a colored cell\n")); 10259 flags &= ~(FG_COLOR | BG_COLOR); 10260 } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) { 10261 TRACE(("ShowCursor - should we treat as a colored cell?\n")); 10262 if (!(xw->flags & FG_COLOR)) 10263 if (CheckBogusForeground(screen, "ShowCursor")) 10264 flags &= ~(FG_COLOR | BG_COLOR); 10265 } 10266 } 10267#else /* !EXP_BOGUS_FG */ 10268 /* 10269 * If the cursor happens to be on blanks, and the foreground color is set 10270 * but not the background, do not treat it as a colored cell. 10271 */ 10272 if ((flags & TERM_COLOR_FLAGS(xw)) == FG_COLOR 10273 && base == ' ') { 10274 flags &= ~TERM_COLOR_FLAGS(xw); 10275 } 10276#endif 10277#endif 10278 10279 /* 10280 * Compare the current cell to the last set of colors used for the 10281 * cursor and update the GC's if needed. 10282 */ 10283 if_OPT_ISO_COLORS(screen, { 10284 fg_bg = ld->color[cursor_col]; 10285 }); 10286 10287 fg_pix = getXtermForeground(xw, flags, (int) extract_fg(xw, fg_bg, flags)); 10288 bg_pix = getXtermBackground(xw, flags, (int) extract_bg(xw, fg_bg, flags)); 10289 10290 /* 10291 * If we happen to have the same foreground/background colors, choose 10292 * a workable foreground color from which we can obtain a visible cursor. 10293 */ 10294 if (fg_pix == bg_pix) { 10295 long bg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_BG)); 10296 long fg_diff = (long) (bg_pix - T_COLOR(TScreenOf(xw), TEXT_FG)); 10297 if (bg_diff < 0) 10298 bg_diff = -bg_diff; 10299 if (fg_diff < 0) 10300 fg_diff = -fg_diff; 10301 if (bg_diff < fg_diff) { 10302 fg_pix = T_COLOR(TScreenOf(xw), TEXT_FG); 10303 } else { 10304 fg_pix = T_COLOR(TScreenOf(xw), TEXT_BG); 10305 } 10306 } 10307 10308 if (OutsideSelection(screen, screen->cur_row, screen->cur_col)) 10309 in_selection = False; 10310 else 10311 in_selection = True; 10312 10313 reversed = ReverseOrHilite(screen, flags, in_selection); 10314 10315 /* This is like updatedXtermGC(), except that we have to worry about 10316 * whether the window has focus, since in that case we want just an 10317 * outline for the cursor. 10318 */ 10319 filled = (screen->select || screen->always_highlight) && isCursorBlock(screen); 10320#if OPT_HIGHLIGHT_COLOR 10321 use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix); 10322 use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix); 10323#endif 10324 if (filled) { 10325 if (reversed) { /* text is reverse video */ 10326 if (getCgsGC(xw, currentWin, gcVTcursNormal)) { 10327 setGC(gcVTcursNormal); 10328 } else { 10329 if (flags & BOLDATTR(screen)) { 10330 setGC(gcBold); 10331 } else { 10332 setGC(gcNorm); 10333 } 10334 } 10335 EXCHANGE(fg_pix, bg_pix, tmp); 10336#if OPT_HIGHLIGHT_COLOR 10337 if (screen->hilite_reverse) { 10338 if (use_selbg && !use_selfg) 10339 fg_pix = bg_pix; 10340 if (use_selfg && !use_selbg) 10341 bg_pix = fg_pix; 10342 if (use_selbg) 10343 bg_pix = selbg_pix; 10344 if (use_selfg) 10345 fg_pix = selfg_pix; 10346 } 10347#endif 10348 } else { /* normal video */ 10349 if (getCgsGC(xw, currentWin, gcVTcursReverse)) { 10350 setGC(gcVTcursReverse); 10351 } else { 10352 if (flags & BOLDATTR(screen)) { 10353 setGC(gcBoldReverse); 10354 } else { 10355 setGC(gcNormReverse); 10356 } 10357 } 10358 } 10359 10360#define CUR_XX T_COLOR(screen, TEXT_CURSOR) 10361#define CGS_FG getCgsFore(xw, currentWin, getCgsGC(xw, currentWin, currentCgs)) 10362#define CGS_BG getCgsBack(xw, currentWin, getCgsGC(xw, currentWin, currentCgs)) 10363 10364#define FIX_311 (CUR_XX == (reversed ? xw->dft_background : xw->dft_foreground)) 10365#define FIX_328 (CUR_XX == bg_pix) 10366#define FIX_330 (FIX_328 && reversed && in_selection) 10367 10368 if (FIX_330 || FIX_311) { 10369 setCgsBack(xw, currentWin, currentCgs, fg_pix); 10370 } 10371 setCgsFore(xw, currentWin, currentCgs, bg_pix); 10372 } else { /* not selected */ 10373 if (reversed) { /* text is reverse video */ 10374 EXCHANGE(fg_pix, bg_pix, tmp); 10375 setGC(gcNormReverse); 10376 } else { /* normal video */ 10377 setGC(gcNorm); 10378 } 10379#if OPT_HIGHLIGHT_COLOR 10380 if (screen->hilite_reverse) { 10381 if (in_selection && !reversed) { 10382 /* EMPTY */ 10383 /* really INVERSE ... */ 10384 ; 10385 } else if (in_selection || reversed) { 10386 if (use_selbg) { 10387 if (use_selfg) { 10388 bg_pix = fg_pix; 10389 } else { 10390 fg_pix = bg_pix; 10391 } 10392 } 10393 if (use_selbg) { 10394 bg_pix = selbg_pix; 10395 } 10396 if (use_selfg) { 10397 fg_pix = selfg_pix; 10398 } 10399 } 10400 } else { 10401 if (in_selection) { 10402 if (use_selbg) { 10403 bg_pix = selbg_pix; 10404 } 10405 if (use_selfg) { 10406 fg_pix = selfg_pix; 10407 } 10408 } 10409 } 10410#endif 10411 setCgsFore(xw, currentWin, currentCgs, fg_pix); 10412 setCgsBack(xw, currentWin, currentCgs, bg_pix); 10413 } 10414 10415 if (screen->cursor_busy == 0 10416 && (screen->cursor_state != ON || screen->cursor_GC != set_at)) { 10417 int x, y; 10418 10419 screen->cursor_GC = set_at; 10420 TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n", 10421 screen->cur_row, screen->cur_col, 10422 (filled ? "filled" : "outline"), 10423 (isCursorBlock(screen) ? "box" : 10424 isCursorUnderline(screen) ? "underline" : "bar"), 10425 set_at)); 10426 10427 currentGC = getCgsGC(xw, currentWin, currentCgs); 10428 x = LineCursorX(screen, ld, cursor_col); 10429 y = CursorY(screen, screen->cur_row); 10430 10431 if (!isCursorBlock(screen)) { 10432 /* 10433 * Overriding the combination of filled, reversed, in_selection is 10434 * too complicated since the underline or bar and the text-cell use 10435 * different rules. Just redraw the text-cell, and draw the 10436 * underline or bar on top of it. 10437 */ 10438 HideCursor(); 10439 10440 /* 10441 * Our current-GC is likely to have been modified in HideCursor(). 10442 * Set up a new request. 10443 */ 10444 if (filled) { 10445 if (FIX_330 || FIX_311) { 10446 setCgsBack(xw, currentWin, currentCgs, fg_pix); 10447 } 10448 setCgsFore(xw, currentWin, currentCgs, bg_pix); 10449 } else { 10450 setCgsFore(xw, currentWin, currentCgs, fg_pix); 10451 setCgsBack(xw, currentWin, currentCgs, bg_pix); 10452 } 10453 } 10454 10455 /* 10456 * Update the outline-gc, to keep the cursor color distinct from the 10457 * background color. 10458 */ 10459 set_cursor_outline_gc(xw, 10460 filled, 10461 fg_pix, 10462 bg_pix, 10463 T_COLOR(screen, TEXT_CURSOR)); 10464 10465 outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline); 10466 if (outlineGC == 0) 10467 outlineGC = currentGC; 10468 10469 if (isCursorUnderline(screen)) { 10470 10471 /* 10472 * Finally, draw the underline. 10473 */ 10474 screen->box->x = (short) x; 10475 screen->box->y = (short) (y + FontHeight(screen) - 2); 10476 XDrawLines(screen->display, VDrawable(screen), outlineGC, 10477 screen->box, NBOX, CoordModePrevious); 10478 } else if (isCursorBar(screen)) { 10479 10480 /* 10481 * Or draw the bar. 10482 */ 10483 screen->box->x = (short) x; 10484 screen->box->y = (short) y; 10485 XDrawLines(screen->display, VWindow(screen), outlineGC, 10486 screen->box, NBOX, CoordModePrevious); 10487 } else { 10488#if OPT_WIDE_ATTRS 10489 int italics_on = ((ld->attribs[cursor_col] & ATR_ITALIC) != 0); 10490 int italics_off = ((xw->flags & ATR_ITALIC) != 0); 10491 int fix_italics = (italics_on != italics_off); 10492 int which_font = ((xw->flags & BOLD) ? fBold : fNorm); 10493 10494 if_OPT_WIDE_CHARS(screen, { 10495 if (isWide((int) base)) { 10496 which_font = ((xw->flags & BOLD) ? fWBold : fWide); 10497 } 10498 }); 10499 10500 if (fix_italics && UseItalicFont(screen)) { 10501 xtermLoadItalics(xw); 10502 if (italics_on) { 10503 setCgsFont(xw, currentWin, currentCgs, 10504 getItalicFont(screen, which_font)); 10505 } else { 10506 setCgsFont(xw, currentWin, currentCgs, 10507 getNormalFont(screen, which_font)); 10508 } 10509 } 10510 currentGC = getCgsGC(xw, currentWin, currentCgs); 10511#endif /* OPT_WIDE_ATTRS */ 10512 10513 drawXtermText(xw, 10514 flags & DRAWX_MASK, 10515 0, 10516 currentGC, x, y, 10517 LineCharSet(screen, ld), 10518 &base, 1, 0); 10519 10520#if OPT_WIDE_CHARS 10521 if_OPT_WIDE_CHARS(screen, { 10522 size_t off; 10523 for_each_combData(off, ld) { 10524 if (!(ld->combData[off][my_col])) 10525 break; 10526 drawXtermText(xw, 10527 (flags & DRAWX_MASK), 10528 NOBACKGROUND, 10529 currentGC, x, y, 10530 LineCharSet(screen, ld), 10531 ld->combData[off] + my_col, 10532 1, isWide((int) base)); 10533 } 10534 }); 10535#endif 10536 10537 if (!filled) { 10538 screen->box->x = (short) x; 10539 screen->box->y = (short) y; 10540 XDrawLines(screen->display, VDrawable(screen), outlineGC, 10541 screen->box, NBOX, CoordModePrevious); 10542 } 10543#if OPT_WIDE_ATTRS 10544 if (fix_italics && UseItalicFont(screen)) { 10545 if (italics_on) { 10546 setCgsFont(xw, currentWin, currentCgs, 10547 getNormalFont(screen, which_font)); 10548 } else { 10549 setCgsFont(xw, currentWin, currentCgs, 10550 getItalicFont(screen, which_font)); 10551 } 10552 } 10553#endif 10554 } 10555 } 10556 screen->cursor_state = ON; 10557 10558 return; 10559} 10560 10561/* 10562 * hide cursor at previous cursor position in screen. 10563 */ 10564void 10565HideCursor(void) 10566{ 10567 XtermWidget xw = term; 10568 TScreen *screen = TScreenOf(xw); 10569 GC currentGC; 10570 int x, y; 10571 IChar base; 10572 unsigned flags; 10573 CellColor fg_bg = 0; 10574 Bool in_selection; 10575#if OPT_WIDE_CHARS 10576 int my_col = 0; 10577#endif 10578 int cursor_col; 10579 CLineData *ld = 0; 10580#if OPT_WIDE_ATTRS 10581 int which_Cgs = gcMAX; 10582 unsigned attr_flags; 10583 int which_font = fNorm; 10584#endif 10585 10586 if (screen->cursor_state == OFF) 10587 return; 10588 if (INX2ROW(screen, screen->cursorp.row) > screen->max_row) 10589 return; 10590 10591 cursor_col = screen->cursorp.col; 10592 10593#ifndef NO_ACTIVE_ICON 10594 if (IsIcon(screen)) { 10595 screen->cursor_state = OFF; 10596 return; 10597 } 10598#endif /* NO_ACTIVE_ICON */ 10599 10600 ld = getLineData(screen, screen->cursorp.row); 10601 10602 base = ld->charData[cursor_col]; 10603 flags = ld->attribs[cursor_col]; 10604 10605 if_OPT_WIDE_CHARS(screen, { 10606 if (base == HIDDEN_CHAR && cursor_col > 0) { 10607 /* if cursor points to non-initial part of wide character, 10608 * back it up 10609 */ 10610 --cursor_col; 10611 base = ld->charData[cursor_col]; 10612 } 10613 my_col = cursor_col; 10614 if (base == 0) 10615 base = ' '; 10616 if (isWide((int) base)) 10617 my_col += 1; 10618 }); 10619 10620 if (base == 0) { 10621 base = ' '; 10622 } 10623#ifdef EXP_BOGUS_FG 10624 /* 10625 * If the cursor happens to be on blanks, and we have not set both 10626 * foreground and background color, do not treat it as a colored cell. 10627 */ 10628#if OPT_ISO_COLORS 10629 if (base == ' ') { 10630 if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) { 10631 TRACE(("HideCursor - do not treat as a colored cell\n")); 10632 flags &= ~(FG_COLOR | BG_COLOR); 10633 } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) { 10634 TRACE(("HideCursor - should we treat as a colored cell?\n")); 10635 if (!(xw->flags & FG_COLOR)) 10636 if (CheckBogusForeground(screen, "HideCursor")) 10637 flags &= ~(FG_COLOR | BG_COLOR); 10638 } 10639 } 10640#endif 10641#endif 10642#if OPT_ISO_COLORS 10643 fg_bg = 0; 10644#endif 10645 10646 /* 10647 * Compare the current cell to the last set of colors used for the 10648 * cursor and update the GC's if needed. 10649 */ 10650 if_OPT_ISO_COLORS(screen, { 10651 fg_bg = ld->color[cursor_col]; 10652 }); 10653 10654 if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col)) 10655 in_selection = False; 10656 else 10657 in_selection = True; 10658 10659#if OPT_WIDE_ATTRS 10660 attr_flags = ld->attribs[cursor_col]; 10661 if ((attr_flags & ATR_ITALIC) ^ (xw->flags & ATR_ITALIC)) { 10662 which_font = ((attr_flags & BOLD) ? fBold : fNorm); 10663 10664 if_OPT_WIDE_CHARS(screen, { 10665 if (isWide((int) base)) { 10666 which_font = ((attr_flags & BOLD) ? fWBold : fWide); 10667 } 10668 }); 10669 10670 which_Cgs = reverseCgs(xw, attr_flags, in_selection, which_font); 10671 if (which_Cgs != gcMAX) { 10672 setCgsFont(xw, WhichVWin(screen), 10673 (CgsEnum) which_Cgs, 10674 (((attr_flags & ATR_ITALIC) && UseItalicFont(screen)) 10675 ? getItalicFont(screen, which_font) 10676 : getNormalFont(screen, which_font))); 10677 } 10678 } 10679#endif 10680 10681 currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection); 10682 10683 TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n", 10684 screen->cursorp.row, screen->cursorp.col)); 10685 10686 x = LineCursorX(screen, ld, cursor_col); 10687 y = CursorY(screen, screen->cursorp.row); 10688 10689 drawXtermText(xw, 10690 flags & DRAWX_MASK, 10691 0, 10692 currentGC, x, y, 10693 LineCharSet(screen, ld), 10694 &base, 1, 0); 10695 10696#if OPT_WIDE_CHARS 10697 if_OPT_WIDE_CHARS(screen, { 10698 size_t off; 10699 for_each_combData(off, ld) { 10700 if (!(ld->combData[off][my_col])) 10701 break; 10702 drawXtermText(xw, 10703 (flags & DRAWX_MASK), 10704 NOBACKGROUND, 10705 currentGC, x, y, 10706 LineCharSet(screen, ld), 10707 ld->combData[off] + my_col, 10708 1, isWide((int) base)); 10709 } 10710 }); 10711#endif 10712 screen->cursor_state = OFF; 10713 10714#if OPT_WIDE_ATTRS 10715 if (which_Cgs != gcMAX) { 10716 setCgsFont(xw, WhichVWin(screen), 10717 (CgsEnum) which_Cgs, 10718 (((xw->flags & ATR_ITALIC) && UseItalicFont(screen)) 10719 ? getItalicFont(screen, which_font) 10720 : getNormalFont(screen, which_font))); 10721 } 10722#endif 10723 resetXtermGC(xw, flags, in_selection); 10724 10725 refresh_displayed_graphics(xw, 10726 screen->cursorp.col, 10727 screen->cursorp.row, 10728 1, 1); 10729 10730 return; 10731} 10732 10733#if OPT_BLINK_CURS || OPT_BLINK_TEXT 10734static void 10735StartBlinking(TScreen *screen) 10736{ 10737 if (screen->blink_timer == 0) { 10738 unsigned long interval = (unsigned long) ((screen->cursor_state == ON) 10739 ? screen->blink_on 10740 : screen->blink_off); 10741 if (interval == 0) /* wow! */ 10742 interval = 1; /* let's humor him anyway */ 10743 screen->blink_timer = XtAppAddTimeOut(app_con, 10744 interval, 10745 HandleBlinking, 10746 screen); 10747 } 10748} 10749 10750static void 10751StopBlinking(TScreen *screen) 10752{ 10753 if (screen->blink_timer) { 10754 XtRemoveTimeOut(screen->blink_timer); 10755 screen->blink_timer = 0; 10756 reallyStopBlinking(screen); 10757 } else { 10758 screen->blink_timer = 0; 10759 } 10760} 10761 10762#if OPT_BLINK_TEXT 10763Bool 10764LineHasBlinking(TScreen *screen, CLineData *ld) 10765{ 10766 Bool result = False; 10767 if (ld != 0) { 10768 int col; 10769 10770 for (col = 0; col < MaxCols(screen); ++col) { 10771 if (ld->attribs[col] & BLINK) { 10772 result = True; 10773 break; 10774 } 10775 } 10776 } 10777 return result; 10778} 10779#endif 10780 10781/* 10782 * Blink the cursor by alternately showing/hiding cursor. We leave the timer 10783 * running all the time (even though that's a little inefficient) to make the 10784 * logic simple. 10785 */ 10786static void 10787HandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED) 10788{ 10789 TScreen *screen = (TScreen *) closure; 10790 Bool resume = False; 10791 10792 screen->blink_timer = 0; 10793 screen->blink_state = !screen->blink_state; 10794 10795#if OPT_BLINK_CURS 10796 if (DoStartBlinking(screen)) { 10797 if (screen->cursor_state == ON) { 10798 if (screen->select || screen->always_highlight) { 10799 HideCursor(); 10800 if (screen->cursor_state == OFF) 10801 screen->cursor_state = BLINKED_OFF; 10802 } 10803 } else if (screen->cursor_state == BLINKED_OFF) { 10804 screen->cursor_state = OFF; 10805 ShowCursor(); 10806 if (screen->cursor_state == OFF) 10807 screen->cursor_state = BLINKED_OFF; 10808 } 10809 resume = True; 10810 } 10811#endif 10812 10813#if OPT_BLINK_TEXT 10814 /* 10815 * Inspect the lines on the current screen to see if any have the BLINK flag 10816 * associated with them. Prune off any that have had the corresponding 10817 * cells reset. If any are left, repaint those lines with ScrnRefresh(). 10818 */ 10819 if (!(screen->blink_as_bold)) { 10820 int row; 10821 int first_row = screen->max_row; 10822 int last_row = -1; 10823 10824 for (row = screen->max_row; row >= 0; row--) { 10825 LineData *ld = getLineData(screen, ROW2INX(screen, row)); 10826 10827 if (ld != 0 && LineTstBlinked(ld)) { 10828 if (LineHasBlinking(screen, ld)) { 10829 resume = True; 10830 if (row > last_row) 10831 last_row = row; 10832 if (row < first_row) 10833 first_row = row; 10834 } else { 10835 LineClrBlinked(ld); 10836 } 10837 } 10838 } 10839 /* 10840 * FIXME: this could be a little more efficient, e.g,. by limiting the 10841 * columns which are updated. 10842 */ 10843 if (first_row <= last_row) { 10844 ScrnRefresh(term, 10845 first_row, 10846 0, 10847 last_row + 1 - first_row, 10848 MaxCols(screen), 10849 True); 10850 } 10851 } 10852#endif 10853 10854 /* 10855 * If either the cursor or text is blinking, restart the timer. 10856 */ 10857 if (resume) 10858 StartBlinking(screen); 10859} 10860#endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */ 10861 10862void 10863RestartBlinking(TScreen *screen GCC_UNUSED) 10864{ 10865#if OPT_BLINK_CURS || OPT_BLINK_TEXT 10866 if (screen->blink_timer == 0) { 10867 Bool resume = False; 10868 10869#if OPT_BLINK_CURS 10870 if (DoStartBlinking(screen)) { 10871 resume = True; 10872 } 10873#endif 10874#if OPT_BLINK_TEXT 10875 if (!resume) { 10876 int row; 10877 10878 for (row = screen->max_row; row >= 0; row--) { 10879 CLineData *ld = getLineData(screen, ROW2INX(screen, row)); 10880 10881 if (ld != 0 && LineTstBlinked(ld)) { 10882 if (LineHasBlinking(screen, ld)) { 10883 resume = True; 10884 break; 10885 } 10886 } 10887 } 10888 } 10889#endif 10890 if (resume) 10891 StartBlinking(screen); 10892 } 10893#endif 10894} 10895 10896/* 10897 * Implement soft or hard (full) reset of the VTxxx emulation. There are a 10898 * couple of differences from real DEC VTxxx terminals (to avoid breaking 10899 * applications which have come to rely on xterm doing this): 10900 * 10901 * + autowrap mode should be reset (instead it's reset to the resource 10902 * default). 10903 * + the popup menu offers a choice of resetting the savedLines, or not. 10904 * (but the control sequence does this anyway). 10905 */ 10906static void 10907ReallyReset(XtermWidget xw, Bool full, Bool saved) 10908{ 10909 TScreen *screen = TScreenOf(xw); 10910 10911 if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) { 10912 Bell(xw, XkbBI_MinorError, 0); 10913 return; 10914 } 10915 10916 if (saved) { 10917 screen->savedlines = 0; 10918 ScrollBarDrawThumb(screen->scrollWidget); 10919 } 10920 10921 /* make cursor visible */ 10922 screen->cursor_set = ON; 10923 InitCursorShape(screen, screen); 10924#if OPT_BLINK_CURS 10925 TRACE(("cursor_shape:%d blinks:%s\n", 10926 screen->cursor_shape, 10927 BtoS(screen->cursor_blink))); 10928#endif 10929 10930 /* reset scrolling region */ 10931 reset_margins(screen); 10932 10933 bitclr(&xw->flags, ORIGIN); 10934 10935 if_OPT_ISO_COLORS(screen, { 10936 static char empty[1]; 10937 reset_SGR_Colors(xw); 10938 if (ResetAnsiColorRequest(xw, empty, 0)) 10939 xtermRepaint(xw); 10940 }); 10941 10942 /* Reset character-sets to initial state */ 10943 resetCharsets(screen); 10944 10945#if OPT_MOD_FKEYS 10946 /* Reset modifier-resources to initial state */ 10947 xw->keyboard.modify_now = xw->keyboard.modify_1st; 10948#endif 10949 10950 /* Reset DECSCA */ 10951 bitclr(&xw->flags, PROTECTED); 10952 screen->protected_mode = OFF_PROTECT; 10953 10954 reset_displayed_graphics(screen); 10955 10956 if (full) { /* RIS */ 10957 if (screen->bellOnReset) 10958 Bell(xw, XkbBI_TerminalBell, 0); 10959 10960 /* reset the mouse mode */ 10961 screen->send_mouse_pos = MOUSE_OFF; 10962 screen->send_focus_pos = OFF; 10963 screen->extend_coords = 0; 10964 screen->waitingForTrackInfo = False; 10965 screen->eventMode = NORMAL; 10966 10967 xtermShowPointer(xw, True); 10968 10969 TabReset(xw->tabs); 10970 xw->keyboard.flags = MODE_SRM; 10971 10972 guard_keyboard_type = False; 10973 screen->old_fkeys = screen->old_fkeys0; 10974 decode_keyboard_type(xw, &resource); 10975 update_keyboard_type(); 10976 10977#if OPT_INITIAL_ERASE 10978 if (xw->keyboard.reset_DECBKM == 1) 10979 xw->keyboard.flags |= MODE_DECBKM; 10980 else if (xw->keyboard.reset_DECBKM == 2) 10981#endif 10982 if (TScreenOf(xw)->backarrow_key) 10983 xw->keyboard.flags |= MODE_DECBKM; 10984 TRACE(("full reset DECBKM %s\n", 10985 BtoS(xw->keyboard.flags & MODE_DECBKM))); 10986 10987#if OPT_SCROLL_LOCK 10988 xtermClearLEDs(screen); 10989#endif 10990 screen->title_modes = screen->title_modes0; 10991 screen->pointer_mode = screen->pointer_mode0; 10992#if OPT_SIXEL_GRAPHICS 10993 if (TScreenOf(xw)->sixel_scrolling) 10994 xw->keyboard.flags |= MODE_DECSDM; 10995 TRACE(("full reset DECSDM to %s (resource default is %s)\n", 10996 BtoS(xw->keyboard.flags & MODE_DECSDM), 10997 BtoS(TScreenOf(xw)->sixel_scrolling))); 10998#endif 10999 11000#if OPT_GRAPHICS 11001 screen->privatecolorregisters = TScreenOf(xw)->privatecolorregisters; 11002 TRACE(("full reset PRIVATE_COLOR_REGISTERS to %s (resource default is %s)\n", 11003 BtoS(screen->privatecolorregisters), 11004 BtoS(TScreenOf(xw)->privatecolorregisters))); 11005#endif 11006 11007#if OPT_SIXEL_GRAPHICS 11008 screen->sixel_scrolls_right = TScreenOf(xw)->sixel_scrolls_right; 11009 TRACE(("full reset SIXEL_SCROLLS_RIGHT to %s (resource default is %s)\n", 11010 BtoS(screen->sixel_scrolls_right), 11011 BtoS(TScreenOf(xw)->sixel_scrolls_right))); 11012#endif 11013 11014 update_appcursor(); 11015 update_appkeypad(); 11016 update_decbkm(); 11017 update_decsdm(); 11018 show_8bit_control(False); 11019 reset_decudk(xw); 11020 11021 FromAlternate(xw); 11022 ClearScreen(xw); 11023 screen->cursor_state = OFF; 11024 if (xw->flags & REVERSE_VIDEO) 11025 ReverseVideo(xw); 11026 11027 xw->flags = xw->initflags; 11028 update_reversevideo(); 11029 update_autowrap(); 11030 update_reversewrap(); 11031 update_autolinefeed(); 11032 11033 screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL)); 11034 update_jumpscroll(); 11035 11036#if OPT_DEC_RECTOPS 11037 screen->cur_decsace = 0; 11038#endif 11039#if OPT_READLINE 11040 screen->click1_moves = OFF; 11041 screen->paste_moves = OFF; 11042 screen->dclick3_deletes = OFF; 11043 screen->paste_brackets = OFF; 11044 screen->paste_quotes = OFF; 11045 screen->paste_literal_nl = OFF; 11046#endif /* OPT_READLINE */ 11047 11048 if (screen->c132 && (xw->flags & IN132COLUMNS)) { 11049 Dimension reqWidth = (Dimension) (80 * FontWidth(screen) 11050 + 2 * screen->border 11051 + ScrollbarWidth(screen)); 11052 Dimension reqHeight = (Dimension) (FontHeight(screen) 11053 * MaxRows(screen) 11054 + 2 * screen->border); 11055 Dimension replyWidth; 11056 Dimension replyHeight; 11057 11058 TRACE(("Making resize-request to restore 80-columns %dx%d\n", 11059 reqHeight, reqWidth)); 11060 REQ_RESIZE((Widget) xw, 11061 reqWidth, 11062 reqHeight, 11063 &replyWidth, &replyHeight); 11064 repairSizeHints(); 11065 XSync(screen->display, False); /* synchronize */ 11066 if (xtermAppPending()) 11067 xevents(); 11068 } 11069 11070 CursorSet(screen, 0, 0, xw->flags); 11071 CursorSave(xw); 11072 } else { /* DECSTR */ 11073 /* 11074 * There's a tiny difference, to accommodate usage of xterm. 11075 * We reset autowrap to the resource values rather than turning 11076 * it off. 11077 */ 11078 UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM)); 11079 bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP); 11080 bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE); 11081 if_OPT_ISO_COLORS(screen, { 11082 reset_SGR_Colors(xw); 11083 }); 11084 update_appcursor(); 11085 update_autowrap(); 11086 update_reversewrap(); 11087 11088 CursorSave(xw); 11089 screen->sc[screen->whichBuf].row = 11090 screen->sc[screen->whichBuf].col = 0; 11091 } 11092} 11093 11094void 11095VTReset(XtermWidget xw, Bool full, Bool saved) 11096{ 11097 ReallyReset(xw, full, saved); 11098 longjmp(vtjmpbuf, 1); /* force ground state in parser */ 11099} 11100 11101typedef enum { 11102 ccLO, 11103 ccDASH, 11104 ccHI, 11105 ccCOLON, 11106 ccID, 11107 ccCOMMA 11108} CCLASS; 11109 11110/* 11111 * set_character_class - takes a string of the form 11112 * 11113 * low[-high][:id][,low[-high][:id][...]] 11114 * 11115 * and sets the indicated ranges to the indicated values. 11116 */ 11117static int 11118set_character_class(char *s) 11119{ 11120#define FMT "%s in range string \"%s\" (position %d)\n" 11121 11122 TRACE(("set_character_class(%s) {{\n", NonNull(s))); 11123 if (IsEmpty(s)) { 11124 return -1; 11125 } else { 11126 CCLASS state = ccLO; 11127 int arg[3]; 11128 int i; 11129 int len = (int) strlen(s); 11130 11131 arg[0] = 11132 arg[1] = 11133 arg[2] = -1; 11134 11135 for (i = 0; i < len; ++i) { 11136 int ch = CharOf(s[i]); 11137 char *t = 0; 11138 long value = 0; 11139 11140 if (isspace(ch)) 11141 continue; 11142 11143 switch (state) { 11144 case ccLO: 11145 case ccHI: 11146 case ccID: 11147 if (!isdigit(ch)) { 11148 xtermWarning(FMT, "missing number", s, i); 11149 return (-1); 11150 } 11151 value = strtol(s + i, &t, 0); 11152 i = (int) (t - s - 1); 11153 break; 11154 case ccDASH: 11155 case ccCOLON: 11156 case ccCOMMA: 11157 break; 11158 } 11159 11160 switch (state) { 11161 case ccLO: 11162 arg[0] = 11163 arg[1] = (int) value; 11164 arg[2] = -1; 11165 state = ccDASH; 11166 break; 11167 11168 case ccDASH: 11169 if (ch == '-') { 11170 state = ccHI; 11171 } else { 11172 goto parse_class; 11173 } 11174 break; 11175 11176 case ccHI: 11177 arg[1] = (int) value; 11178 state = ccCOLON; 11179 break; 11180 11181 parse_class: 11182 case ccCOLON: 11183 if (ch == ':') { 11184 state = ccID; 11185 } else if (ch == ',') { 11186 goto apply_class; 11187 } else { 11188 xtermWarning(FMT, "unexpected character", s, i); 11189 return (-1); 11190 } 11191 break; 11192 11193 case ccID: 11194 arg[2] = (int) value; 11195 state = ccCOMMA; 11196 break; 11197 11198 apply_class: 11199 case ccCOMMA: 11200 if (SetCharacterClassRange(arg[0], arg[1], arg[2]) != 0) { 11201 xtermWarning(FMT, "bad range", s, i); 11202 return -1; 11203 } 11204 state = ccLO; 11205 break; 11206 } 11207 } 11208 if (state >= ccDASH) { 11209 if (SetCharacterClassRange(arg[0], arg[1], arg[2]) != 0) { 11210 xtermWarning(FMT, "bad range", s, i); 11211 return -1; 11212 } 11213 } 11214 } 11215 11216 TRACE(("}} set_character_class\n")); 11217 return (0); 11218#undef FMT 11219} 11220 11221void 11222getKeymapResources(Widget w, 11223 const char *mapName, 11224 const char *mapClass, 11225 const char *type, 11226 void *result, 11227 size_t size) 11228{ 11229 XtResource key_resources[1]; 11230 key_resources[0].resource_name = XtNtranslations; 11231 key_resources[0].resource_class = XtCTranslations; 11232 key_resources[0].resource_type = (char *) type; 11233 key_resources[0].resource_size = (Cardinal) size; 11234 key_resources[0].resource_offset = 0; 11235 key_resources[0].default_type = key_resources[0].resource_type; 11236 key_resources[0].default_addr = 0; 11237 XtGetSubresources(w, (XtPointer) result, mapName, mapClass, 11238 key_resources, (Cardinal) 1, NULL, (Cardinal) 0); 11239} 11240 11241/* ARGSUSED */ 11242static void 11243HandleKeymapChange(Widget w, 11244 XEvent *event GCC_UNUSED, 11245 String *params, 11246 Cardinal *param_count) 11247{ 11248 static XtTranslations keymap, original; 11249 11250 TRACE(("HandleKeymapChange(%#lx, %s)\n", 11251 (unsigned long) w, 11252 (*param_count 11253 ? params[0] 11254 : "missing"))); 11255 11256 if (*param_count != 1) 11257 return; 11258 11259 if (original == NULL) { 11260 TRACE(("...saving original keymap-translations\n")); 11261 original = w->core.tm.translations; 11262 } 11263 11264 if (strcmp(params[0], "None") == 0) { 11265 TRACE(("...restoring original keymap-translations\n")); 11266 XtOverrideTranslations(w, original); 11267 } else { 11268 char mapName[1000]; 11269 char mapClass[1000]; 11270 char *pmapName; 11271 char *pmapClass; 11272 size_t len; 11273 11274 len = strlen(params[0]) + 7; 11275 11276 pmapName = (char *) MyStackAlloc(len, mapName); 11277 pmapClass = (char *) MyStackAlloc(len, mapClass); 11278 if (pmapName == NULL 11279 || pmapClass == NULL) { 11280 SysError(ERROR_KMMALLOC1); 11281 } else { 11282 11283 (void) sprintf(pmapName, "%sKeymap", params[0]); 11284 (void) strcpy(pmapClass, pmapName); 11285 if (islower(CharOf(pmapClass[0]))) 11286 pmapClass[0] = x_toupper(pmapClass[0]); 11287 getKeymapResources(w, pmapName, pmapClass, XtRTranslationTable, 11288 &keymap, sizeof(keymap)); 11289 if (keymap != NULL) { 11290 TRACE(("...applying keymap \"%s\"\n", pmapName)); 11291 XtOverrideTranslations(w, keymap); 11292 } else { 11293 TRACE(("...found no match for keymap \"%s\"\n", pmapName)); 11294 } 11295 11296 MyStackFree(pmapName, mapName); 11297 MyStackFree(pmapClass, mapClass); 11298 } 11299 } 11300} 11301 11302/* ARGSUSED */ 11303static void 11304HandleBell(Widget w GCC_UNUSED, 11305 XEvent *event GCC_UNUSED, 11306 String *params, /* [0] = volume */ 11307 Cardinal *param_count) /* 0 or 1 */ 11308{ 11309 int percent = (*param_count) ? atoi(params[0]) : 0; 11310 11311 Bell(term, XkbBI_TerminalBell, percent); 11312} 11313 11314/* ARGSUSED */ 11315static void 11316HandleVisualBell(Widget w GCC_UNUSED, 11317 XEvent *event GCC_UNUSED, 11318 String *params GCC_UNUSED, 11319 Cardinal *param_count GCC_UNUSED) 11320{ 11321 VisualBell(); 11322} 11323 11324/* ARGSUSED */ 11325static void 11326HandleIgnore(Widget w, 11327 XEvent *event, 11328 String *params GCC_UNUSED, 11329 Cardinal *param_count GCC_UNUSED) 11330{ 11331 XtermWidget xw; 11332 11333 TRACE(("Handle ignore for %p %s\n", 11334 (void *) w, visibleEventType(event->type))); 11335 if ((xw = getXtermWidget(w)) != 0) { 11336 /* do nothing, but check for funny escape sequences */ 11337 (void) SendMousePosition(xw, event); 11338 } 11339} 11340 11341/* ARGSUSED */ 11342static void 11343DoSetSelectedFont(Widget w, 11344 XtPointer client_data GCC_UNUSED, 11345 Atom *selection GCC_UNUSED, 11346 Atom *type, 11347 XtPointer value, 11348 unsigned long *length, 11349 int *format) 11350{ 11351 XtermWidget xw = getXtermWidget(w); 11352 11353 if (xw == 0) { 11354 xtermWarning("unexpected widget in DoSetSelectedFont\n"); 11355 } else if (*type != XA_STRING || *format != 8) { 11356 Bell(xw, XkbBI_MinorError, 0); 11357 } else { 11358 Boolean failed = False; 11359 int oldFont = TScreenOf(xw)->menu_font_number; 11360 char *save = TScreenOf(xw)->SelectFontName(); 11361 char *val; 11362 char *test = 0; 11363 unsigned len = (unsigned) *length; 11364 unsigned tst; 11365 11366 /* 11367 * Some versions of X deliver null-terminated selections, some do not. 11368 */ 11369 for (tst = 0; tst < len; ++tst) { 11370 if (((char *) value)[tst] == '\0') { 11371 len = tst; 11372 break; 11373 } 11374 } 11375 11376 if (len > 0 && (val = TypeMallocN(char, len + 1)) != 0) { 11377 char *used; 11378 11379 memcpy(val, value, (size_t) len); 11380 val[len] = '\0'; 11381 used = x_strtrim(val); 11382 TRACE(("DoSetSelectedFont(%s)\n", used)); 11383 /* Do some sanity checking to avoid sending a long selection 11384 back to the server in an OpenFont that is unlikely to succeed. 11385 XLFD allows up to 255 characters and no control characters; 11386 we are a little more liberal here. */ 11387 if (len < 1000 11388 && used != 0 11389 && !strchr(used, '\n') 11390 && (test = x_strdup(used)) != 0) { 11391 TScreenOf(xw)->SelectFontName() = test; 11392 if (!xtermLoadFont(term, 11393 xtermFontName(used), 11394 True, 11395 fontMenu_fontsel)) { 11396 failed = True; 11397 free(test); 11398 TScreenOf(xw)->SelectFontName() = save; 11399 } 11400 } else { 11401 failed = True; 11402 } 11403 if (failed) { 11404 (void) xtermLoadFont(term, 11405 xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)), 11406 True, 11407 oldFont); 11408 Bell(xw, XkbBI_MinorError, 0); 11409 } 11410 free(used); 11411 free(val); 11412 } 11413 } 11414} 11415 11416void 11417FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe) 11418{ 11419 TScreen *screen = TScreenOf(xw); 11420 static AtomPtr *atoms; 11421 static unsigned int atomCount = 0; 11422 AtomPtr *pAtom; 11423 unsigned a; 11424 Atom target; 11425 11426 if (!atom_name) 11427 atom_name = ((screen->mappedSelect && atomCount) 11428 ? screen->mappedSelect[0] 11429 : "PRIMARY"); 11430 TRACE(("FindFontSelection(%s)\n", atom_name)); 11431 11432 for (pAtom = atoms, a = atomCount; a; a--, pAtom++) { 11433 if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0) { 11434 TRACE(("...found atom %d:%s\n", a + 1, atom_name)); 11435 break; 11436 } 11437 } 11438 if (!a) { 11439 atoms = TypeXtReallocN(AtomPtr, atoms, atomCount + 1); 11440 *(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name); 11441 ++atomCount; 11442 TRACE(("...added atom %d:%s\n", atomCount, atom_name)); 11443 } 11444 11445 target = XmuInternAtom(XtDisplay(xw), *pAtom); 11446 if (justprobe) { 11447 screen->SelectFontName() = 11448 XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : 0; 11449 TRACE(("...selected fontname '%s'\n", 11450 NonNull(screen->SelectFontName()))); 11451 } else { 11452 XtGetSelectionValue((Widget) xw, target, XA_STRING, 11453 DoSetSelectedFont, NULL, 11454 XtLastTimestampProcessed(XtDisplay(xw))); 11455 } 11456 return; 11457} 11458 11459Bool 11460set_cursor_gcs(XtermWidget xw) 11461{ 11462 TScreen *screen = TScreenOf(xw); 11463 VTwin *win = WhichVWin(screen); 11464 11465 Pixel cc = T_COLOR(screen, TEXT_CURSOR); 11466 Pixel fg = T_COLOR(screen, TEXT_FG); 11467 Pixel bg = T_COLOR(screen, TEXT_BG); 11468 Bool changed = False; 11469 11470 /* 11471 * Let's see, there are three things that have "color": 11472 * 11473 * background 11474 * text 11475 * cursorblock 11476 * 11477 * And, there are four situations when drawing a cursor, if we decide 11478 * that we like have a solid block of cursor color with the letter 11479 * that it is highlighting shown in the background color to make it 11480 * stand out: 11481 * 11482 * selected window, normal video - background on cursor 11483 * selected window, reverse video - foreground on cursor 11484 * unselected window, normal video - foreground on background 11485 * unselected window, reverse video - background on foreground 11486 * 11487 * Since the last two are really just normalGC and reverseGC, we only 11488 * need two new GC's. Under monochrome, we get the same effect as 11489 * above by setting cursor color to foreground. 11490 */ 11491 11492 TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg)); 11493 if (win != 0 && (cc != bg)) { 11494 /* set the fonts to the current one */ 11495 setCgsFont(xw, win, gcVTcursNormal, 0); 11496 setCgsFont(xw, win, gcVTcursFilled, 0); 11497 setCgsFont(xw, win, gcVTcursReverse, 0); 11498 setCgsFont(xw, win, gcVTcursOutline, 0); 11499 11500 /* we have a colored cursor */ 11501 setCgsFore(xw, win, gcVTcursNormal, fg); 11502 setCgsBack(xw, win, gcVTcursNormal, cc); 11503 11504 setCgsFore(xw, win, gcVTcursFilled, cc); 11505 setCgsBack(xw, win, gcVTcursFilled, fg); 11506 11507 if (screen->always_highlight) { 11508 /* both GC's use the same color */ 11509 setCgsFore(xw, win, gcVTcursReverse, bg); 11510 setCgsBack(xw, win, gcVTcursReverse, cc); 11511 } else { 11512 setCgsFore(xw, win, gcVTcursReverse, bg); 11513 setCgsBack(xw, win, gcVTcursReverse, cc); 11514 } 11515 set_cursor_outline_gc(xw, screen->always_highlight, fg, bg, cc); 11516 changed = True; 11517 } 11518 11519 if (changed) { 11520 TRACE(("...set_cursor_gcs - done\n")); 11521 } 11522 return changed; 11523} 11524 11525/* 11526 * Build up the default translations string, allowing the user to suppress 11527 * some of the features. 11528 */ 11529void 11530VTInitTranslations(void) 11531{ 11532 /* *INDENT-OFF* */ 11533 static struct { 11534 Boolean wanted; 11535 const char *name; 11536 const char *value; 11537 } table[] = { 11538 { 11539 False, 11540 "default", 11541"\ 11542 Shift <KeyPress> Prior:scroll-back(1,halfpage) \n\ 11543 Shift <KeyPress> Next:scroll-forw(1,halfpage) \n\ 11544 Shift <KeyPress> Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\ 11545 Shift <KeyPress> Insert:insert-selection(SELECT, CUT_BUFFER0) \n\ 11546" 11547 }, 11548#if OPT_MAXIMIZE 11549 { 11550 False, 11551 "fullscreen", 11552"\ 11553 Alt <Key>Return:fullscreen() \n\ 11554" 11555 }, 11556#endif 11557#if OPT_SCROLL_LOCK 11558 { 11559 False, 11560 "scroll-lock", 11561"\ 11562 <KeyRelease> Scroll_Lock:scroll-lock() \n\ 11563" 11564 }, 11565#endif 11566#if OPT_SHIFT_FONTS 11567 { 11568 False, 11569 "shift-fonts", 11570"\ 11571 Shift~Ctrl <KeyPress> KP_Add:larger-vt-font() \n\ 11572 Shift Ctrl <KeyPress> KP_Add:smaller-vt-font() \n\ 11573 Shift <KeyPress> KP_Subtract:smaller-vt-font() \n\ 11574" 11575 }, 11576#endif 11577 /* PROCURA added "Meta <Btn2Down>:clear-saved-lines()" */ 11578 { 11579 False, 11580 "default", 11581"\ 11582 ~Meta <KeyPress>:insert-seven-bit() \n\ 11583 Meta <KeyPress>:insert-eight-bit() \n\ 11584 !Ctrl <Btn1Down>:popup-menu(mainMenu) \n\ 11585 !Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\ 11586 !Lock Ctrl @Num_Lock <Btn1Down>:popup-menu(mainMenu) \n\ 11587 ! @Num_Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\ 11588 ~Meta <Btn1Down>:select-start() \n\ 11589 ~Meta <Btn1Motion>:select-extend() \n\ 11590 !Ctrl <Btn2Down>:popup-menu(vtMenu) \n\ 11591 !Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\ 11592 !Lock Ctrl @Num_Lock <Btn2Down>:popup-menu(vtMenu) \n\ 11593 ! @Num_Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\ 11594 ~Ctrl ~Meta <Btn2Down>:ignore() \n\ 11595 Meta <Btn2Down>:clear-saved-lines() \n\ 11596 ~Ctrl ~Meta <Btn2Up>:insert-selection(SELECT, CUT_BUFFER0) \n\ 11597 !Ctrl <Btn3Down>:popup-menu(fontMenu) \n\ 11598 !Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\ 11599 !Lock Ctrl @Num_Lock <Btn3Down>:popup-menu(fontMenu) \n\ 11600 ! @Num_Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\ 11601 ~Ctrl ~Meta <Btn3Down>:start-extend() \n\ 11602 ~Meta <Btn3Motion>:select-extend() \n\ 11603" 11604 }, 11605 { 11606 False, 11607 "wheel-mouse", 11608"\ 11609 Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 11610 Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 11611 Lock @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 11612 @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 11613 <Btn4Down>:scroll-back(5,line,m) \n\ 11614 Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 11615 Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 11616 Lock @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 11617 @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 11618 <Btn5Down>:scroll-forw(5,line,m) \n\ 11619" 11620 }, 11621 { 11622 False, 11623 "default", 11624"\ 11625 <BtnUp>:select-end(SELECT, CUT_BUFFER0) \n\ 11626 <BtnDown>:ignore() \ 11627" 11628 } 11629 }; 11630 /* *INDENT-ON* */ 11631 11632 char *result = 0; 11633 11634 int pass; 11635 Cardinal item; 11636 11637 TRACE(("VTInitTranslations\n")); 11638 for (item = 0; item < XtNumber(table); ++item) { 11639 table[item].wanted = True; 11640 } 11641#if OPT_MAXIMIZE 11642 /* 11643 * As a special case, allow for disabling the alt-enter translation if 11644 * the resource settings prevent fullscreen from being used. We would 11645 * do the same for scroll-lock and shift-fonts if they were application 11646 * resources too, rather than in the widget. 11647 */ 11648 if (resource.fullscreen == esNever) { 11649 for (item = 0; item < XtNumber(table); ++item) { 11650 if (!strcmp(table[item].name, "fullscreen")) { 11651 table[item].wanted = False; 11652 TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value)); 11653 } 11654 } 11655 } 11656#endif 11657 if (!IsEmpty(resource.omitTranslation)) { 11658 char *value; 11659 const char *source = resource.omitTranslation; 11660 11661 while (*source != '\0' && (value = ParseList(&source)) != 0) { 11662 size_t len = strlen(value); 11663 11664 TRACE(("parsed:%s\n", value)); 11665 for (item = 0; item < XtNumber(table); ++item) { 11666 if (strlen(table[item].name) >= len 11667 && x_strncasecmp(table[item].name, 11668 value, 11669 (unsigned) len) == 0) { 11670 table[item].wanted = False; 11671 TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value)); 11672 break; 11673 } 11674 } 11675 free(value); 11676 } 11677 } 11678 11679 for (pass = 0; pass < 2; ++pass) { 11680 size_t needed = 0; 11681 for (item = 0; item < XtNumber(table); ++item) { 11682 if (table[item].wanted) { 11683 if (pass) { 11684 strcat(result, table[item].value); 11685 } else { 11686 needed += strlen(table[item].value) + 1; 11687 } 11688 } 11689 } 11690 if (!pass) { 11691 result = XtMalloc((Cardinal) needed); 11692 *result = '\0'; 11693 } 11694 } 11695 11696 TRACE(("result:\n%s\n", result)); 11697 11698 defaultTranslations = result; 11699 xtermClassRec.core_class.tm_table = result; 11700} 11701 11702#ifdef NO_LEAKS 11703void 11704noleaks_charproc(void) 11705{ 11706 if (v_buffer != 0) 11707 free(v_buffer); 11708} 11709#endif 11710