charproc.c revision a1f3da82
1/* $XTermId: charproc.c,v 1.1112 2011/02/20 00:50:46 tom Exp $ */ 2 3/* 4 * Copyright 1999-2010,2011 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_NEXTAW) 98#include <X11/neXtaw/XawImP.h> 99#elif defined(HAVE_LIB_XAWPLUS) 100#include <X11/XawPlus/XawImP.h> 101#endif 102 103#endif 104 105#if OPT_WIDE_CHARS 106#include <wcwidth.h> 107#include <precompose.h> 108#ifdef HAVE_LANGINFO_CODESET 109#include <langinfo.h> 110#endif 111#endif 112 113#if OPT_INPUT_METHOD 114#include <X11/Xlocale.h> 115#endif 116 117#include <stdio.h> 118#include <ctype.h> 119#include <assert.h> 120 121#if defined(HAVE_SCHED_YIELD) 122#include <sched.h> 123#endif 124 125#include <VTparse.h> 126#include <data.h> 127#include <error.h> 128#include <menu.h> 129#include <main.h> 130#include <fontutils.h> 131#include <xcharmouse.h> 132#include <charclass.h> 133#include <xstrings.h> 134 135typedef void (*BitFunc) (unsigned * /* p */ , 136 unsigned /* mask */ ); 137 138static IChar doinput(void); 139static int set_character_class(char * /*s */ ); 140static void FromAlternate(XtermWidget /* xw */ ); 141static void RequestResize(XtermWidget /* xw */ , 142 int /* rows */ , 143 int /* cols */ , 144 Bool /* text */ ); 145static void SwitchBufs(XtermWidget /* xw */ , 146 int /* toBuf */ ); 147static void ToAlternate(XtermWidget /* xw */ ); 148static void ansi_modes(XtermWidget termw, 149 BitFunc /* func */ ); 150static void bitclr(unsigned *p, unsigned mask); 151static void bitcpy(unsigned *p, unsigned q, unsigned mask); 152static void bitset(unsigned *p, unsigned mask); 153static void dpmodes(XtermWidget /* xw */ , 154 BitFunc /* func */ ); 155static void restoremodes(XtermWidget /* xw */ ); 156static void savemodes(XtermWidget /* xw */ ); 157static void window_ops(XtermWidget /* xw */ ); 158 159#define DoStartBlinking(s) ((s)->cursor_blink ^ (s)->cursor_blink_esc) 160 161#if OPT_BLINK_CURS || OPT_BLINK_TEXT 162static void SetCursorBlink(TScreen * /* screen */ , 163 Bool /* enable */ ); 164static void HandleBlinking(XtPointer /* closure */ , 165 XtIntervalId * /* id */ ); 166static void StartBlinking(TScreen * /* screen */ ); 167static void StopBlinking(TScreen * /* screen */ ); 168#else 169#define StartBlinking(screen) /* nothing */ 170#define StopBlinking(screen) /* nothing */ 171#endif 172 173#if OPT_INPUT_METHOD 174static void PreeditPosition(TScreen * screen); 175#endif 176 177#define DEFAULT -1 178#define BELLSUPPRESSMSEC 200 179 180static int nparam; 181static ANSI reply; 182static int param[NPARAM]; 183 184static jmp_buf vtjmpbuf; 185 186/* event handlers */ 187static void HandleBell PROTO_XT_ACTIONS_ARGS; 188static void HandleIgnore PROTO_XT_ACTIONS_ARGS; 189static void HandleKeymapChange PROTO_XT_ACTIONS_ARGS; 190static void HandleVisualBell PROTO_XT_ACTIONS_ARGS; 191#if HANDLE_STRUCT_NOTIFY 192static void HandleStructNotify PROTO_XT_EV_HANDLER_ARGS; 193#endif 194 195/* 196 * NOTE: VTInitialize zeros out the entire ".screen" component of the 197 * XtermWidget, so make sure to add an assignment statement in VTInitialize() 198 * for each new ".screen" field added to this resource list. 199 */ 200 201/* Defaults */ 202#if OPT_ISO_COLORS 203 204/* 205 * If we default to colorMode enabled, compile-in defaults for the ANSI colors. 206 */ 207#if DFT_COLORMODE 208#define DFT_COLOR(name) name 209#else 210#define DFT_COLOR(name) XtDefaultForeground 211#endif 212#endif 213 214static String _Font_Selected_ = "yes"; /* string is arbitrary */ 215 216static const char *defaultTranslations; 217/* *INDENT-OFF* */ 218static XtActionsRec actionsList[] = { 219 { "allow-send-events", HandleAllowSends }, 220 { "bell", HandleBell }, 221 { "clear-saved-lines", HandleClearSavedLines }, 222 { "copy-selection", HandleCopySelection }, 223 { "create-menu", HandleCreateMenu }, 224 { "delete-is-del", HandleDeleteIsDEL }, 225 { "dired-button", DiredButton }, 226 { "hard-reset", HandleHardReset }, 227 { "ignore", HandleIgnore }, 228 { "insert", HandleKeyPressed }, /* alias for insert-seven-bit */ 229 { "insert-eight-bit", HandleEightBitKeyPressed }, 230 { "insert-selection", HandleInsertSelection }, 231 { "insert-seven-bit", HandleKeyPressed }, 232 { "interpret", HandleInterpret }, 233 { "keymap", HandleKeymapChange }, 234 { "popup-menu", HandlePopupMenu }, 235 { "print", HandlePrintScreen }, 236 { "print-everything", HandlePrintEverything }, 237 { "print-redir", HandlePrintControlMode }, 238 { "quit", HandleQuit }, 239 { "redraw", HandleRedraw }, 240 { "scroll-back", HandleScrollBack }, 241 { "scroll-forw", HandleScrollForward }, 242 { "secure", HandleSecure }, 243 { "select-cursor-end", HandleKeyboardSelectEnd }, 244 { "select-cursor-extend", HandleKeyboardSelectExtend }, 245 { "select-cursor-start", HandleKeyboardSelectStart }, 246 { "select-end", HandleSelectEnd }, 247 { "select-extend", HandleSelectExtend }, 248 { "select-set", HandleSelectSet }, 249 { "select-start", HandleSelectStart }, 250 { "send-signal", HandleSendSignal }, 251 { "set-8-bit-control", Handle8BitControl }, 252 { "set-allow132", HandleAllow132 }, 253 { "set-altscreen", HandleAltScreen }, 254 { "set-appcursor", HandleAppCursor }, 255 { "set-appkeypad", HandleAppKeypad }, 256 { "set-autolinefeed", HandleAutoLineFeed }, 257 { "set-autowrap", HandleAutoWrap }, 258 { "set-backarrow", HandleBackarrow }, 259 { "set-bellIsUrgent", HandleBellIsUrgent }, 260 { "set-cursesemul", HandleCursesEmul }, 261 { "set-jumpscroll", HandleJumpscroll }, 262 { "set-keep-selection", HandleKeepSelection }, 263 { "set-marginbell", HandleMarginBell }, 264 { "set-old-function-keys", HandleOldFunctionKeys }, 265 { "set-pop-on-bell", HandleSetPopOnBell }, 266 { "set-reverse-video", HandleReverseVideo }, 267 { "set-reversewrap", HandleReverseWrap }, 268 { "set-scroll-on-key", HandleScrollKey }, 269 { "set-scroll-on-tty-output", HandleScrollTtyOutput }, 270 { "set-scrollbar", HandleScrollbar }, 271 { "set-select", HandleSetSelect }, 272 { "set-sun-keyboard", HandleSunKeyboard }, 273 { "set-titeInhibit", HandleTiteInhibit }, 274 { "set-visual-bell", HandleSetVisualBell }, 275 { "set-vt-font", HandleSetFont }, 276 { "soft-reset", HandleSoftReset }, 277 { "start-cursor-extend", HandleKeyboardStartExtend }, 278 { "start-extend", HandleStartExtend }, 279 { "string", HandleStringEvent }, 280 { "vi-button", ViButton }, 281 { "visual-bell", HandleVisualBell }, 282#ifdef ALLOWLOGGING 283 { "set-logging", HandleLogging }, 284#endif 285#if OPT_ALLOW_XXX_OPS 286 { "allow-color-ops", HandleAllowColorOps }, 287 { "allow-font-ops", HandleAllowFontOps }, 288 { "allow-tcap-ops", HandleAllowTcapOps }, 289 { "allow-title-ops", HandleAllowTitleOps }, 290 { "allow-window-ops", HandleAllowWindowOps }, 291#endif 292#if OPT_BLINK_CURS 293 { "set-cursorblink", HandleCursorBlink }, 294#endif 295#if OPT_BOX_CHARS 296 { "set-font-linedrawing", HandleFontBoxChars }, 297 { "set-font-packed", HandleFontPacked }, 298#endif 299#if OPT_DABBREV 300 { "dabbrev-expand", HandleDabbrevExpand }, 301#endif 302#if OPT_DEC_CHRSET 303 { "set-font-doublesize", HandleFontDoublesize }, 304#endif 305#if OPT_DEC_SOFTFONT 306 { "set-font-loading", HandleFontLoading }, 307#endif 308#if OPT_EXEC_XTERM 309 { "spawn-new-terminal", HandleSpawnTerminal }, 310#endif 311#if OPT_HP_FUNC_KEYS 312 { "set-hp-function-keys", HandleHpFunctionKeys }, 313#endif 314#if OPT_LOAD_VTFONTS 315 { "load-vt-fonts", HandleLoadVTFonts }, 316#endif 317#if OPT_MAXIMIZE 318 { "deiconify", HandleDeIconify }, 319 { "fullscreen", HandleFullscreen }, 320 { "iconify", HandleIconify }, 321 { "maximize", HandleMaximize }, 322 { "restore", HandleRestoreSize }, 323#endif 324#if OPT_NUM_LOCK 325 { "alt-sends-escape", HandleAltEsc }, 326 { "meta-sends-escape", HandleMetaEsc }, 327 { "set-num-lock", HandleNumLock }, 328#endif 329#if OPT_READLINE 330 { "readline-button", ReadLineButton }, 331#endif 332#if OPT_RENDERFONT 333 { "set-render-font", HandleRenderFont }, 334#endif 335#if OPT_SCO_FUNC_KEYS 336 { "set-sco-function-keys", HandleScoFunctionKeys }, 337#endif 338#if OPT_SCROLL_LOCK 339 { "scroll-lock", HandleScrollLock }, 340#endif 341#if OPT_SHIFT_FONTS 342 { "larger-vt-font", HandleLargerFont }, 343 { "smaller-vt-font", HandleSmallerFont }, 344#endif 345#if OPT_SUN_FUNC_KEYS 346 { "set-sun-function-keys", HandleSunFunctionKeys }, 347#endif 348#if OPT_TEK4014 349 { "set-terminal-type", HandleSetTerminalType }, 350 { "set-visibility", HandleVisibility }, 351 { "set-tek-text", HandleSetTekText }, 352 { "tek-page", HandleTekPage }, 353 { "tek-reset", HandleTekReset }, 354 { "tek-copy", HandleTekCopy }, 355#endif 356#if OPT_TOOLBAR 357 { "set-toolbar", HandleToolbar }, 358#endif 359#if OPT_WIDE_CHARS 360 { "set-utf8-mode", HandleUTF8Mode }, 361 { "set-utf8-title", HandleUTF8Title }, 362#endif 363}; 364/* *INDENT-ON* */ 365 366static XtResource xterm_resources[] = 367{ 368 Bres(XtNallowSendEvents, XtCAllowSendEvents, screen.allowSendEvent0, False), 369 Bres(XtNallowColorOps, XtCAllowColorOps, screen.allowColorOp0, DEF_ALLOW_COLOR), 370 Bres(XtNallowFontOps, XtCAllowFontOps, screen.allowFontOp0, DEF_ALLOW_FONT), 371 Bres(XtNallowTcapOps, XtCAllowTcapOps, screen.allowTcapOp0, DEF_ALLOW_TCAP), 372 Bres(XtNallowTitleOps, XtCAllowTitleOps, screen.allowTitleOp0, DEF_ALLOW_TITLE), 373 Bres(XtNallowWindowOps, XtCAllowWindowOps, screen.allowWindowOp0, DEF_ALLOW_WINDOW), 374 Bres(XtNaltIsNotMeta, XtCAltIsNotMeta, screen.alt_is_not_meta, False), 375 Bres(XtNaltSendsEscape, XtCAltSendsEscape, screen.alt_sends_esc, False), 376 Bres(XtNalwaysBoldMode, XtCAlwaysBoldMode, screen.always_bold_mode, False), 377 Bres(XtNalwaysHighlight, XtCAlwaysHighlight, screen.always_highlight, False), 378 Bres(XtNappcursorDefault, XtCAppcursorDefault, misc.appcursorDefault, False), 379 Bres(XtNappkeypadDefault, XtCAppkeypadDefault, misc.appkeypadDefault, False), 380 Bres(XtNautoWrap, XtCAutoWrap, misc.autoWrap, True), 381 Bres(XtNawaitInput, XtCAwaitInput, screen.awaitInput, False), 382 Bres(XtNfreeBoldBox, XtCFreeBoldBox, screen.free_bold_box, False), 383 Bres(XtNbackarrowKey, XtCBackarrowKey, screen.backarrow_key, True), 384 Bres(XtNbellIsUrgent, XtCBellIsUrgent, screen.bellIsUrgent, False), 385 Bres(XtNbellOnReset, XtCBellOnReset, screen.bellOnReset, True), 386 Bres(XtNboldMode, XtCBoldMode, screen.bold_mode, True), 387 Bres(XtNbrokenSelections, XtCBrokenSelections, screen.brokenSelections, False), 388 Bres(XtNc132, XtCC132, screen.c132, False), 389 Bres(XtNcurses, XtCCurses, screen.curses, False), 390 Bres(XtNcutNewline, XtCCutNewline, screen.cutNewline, True), 391 Bres(XtNcutToBeginningOfLine, XtCCutToBeginningOfLine, 392 screen.cutToBeginningOfLine, True), 393 Bres(XtNdeleteIsDEL, XtCDeleteIsDEL, screen.delete_is_del, DEFDELETE_DEL), 394 Bres(XtNdynamicColors, XtCDynamicColors, misc.dynamicColors, True), 395 Bres(XtNeightBitControl, XtCEightBitControl, screen.control_eight_bits, False), 396 Bres(XtNeightBitInput, XtCEightBitInput, screen.input_eight_bits, True), 397 Bres(XtNeightBitOutput, XtCEightBitOutput, screen.output_eight_bits, True), 398 Bres(XtNhighlightSelection, XtCHighlightSelection, 399 screen.highlight_selection, False), 400 Bres(XtNshowWrapMarks, XtCShowWrapMarks, screen.show_wrap_marks, False), 401 Bres(XtNhpLowerleftBugCompat, XtCHpLowerleftBugCompat, screen.hp_ll_bc, False), 402 Bres(XtNi18nSelections, XtCI18nSelections, screen.i18nSelections, True), 403 Bres(XtNfastScroll, XtCFastScroll, screen.fastscroll, False), 404 Bres(XtNjumpScroll, XtCJumpScroll, screen.jumpscroll, True), 405 Bres(XtNkeepSelection, XtCKeepSelection, screen.keepSelection, True), 406 Bres(XtNloginShell, XtCLoginShell, misc.login_shell, False), 407 Bres(XtNmarginBell, XtCMarginBell, screen.marginbell, False), 408 Bres(XtNmetaSendsEscape, XtCMetaSendsEscape, screen.meta_sends_esc, False), 409 Bres(XtNmultiScroll, XtCMultiScroll, screen.multiscroll, False), 410 Bres(XtNoldXtermFKeys, XtCOldXtermFKeys, screen.old_fkeys, False), 411 Bres(XtNpopOnBell, XtCPopOnBell, screen.poponbell, False), 412 Bres(XtNprinterAutoClose, XtCPrinterAutoClose, screen.printer_autoclose, False), 413 Bres(XtNprinterExtent, XtCPrinterExtent, screen.printer_extent, False), 414 Bres(XtNprinterFormFeed, XtCPrinterFormFeed, screen.printer_formfeed, False), 415 Bres(XtNprinterNewLine, XtCPrinterNewLine, screen.printer_newline, True), 416 Bres(XtNquietGrab, XtCQuietGrab, screen.quiet_grab, False), 417 Bres(XtNreverseVideo, XtCReverseVideo, misc.re_verse, False), 418 Bres(XtNreverseWrap, XtCReverseWrap, misc.reverseWrap, False), 419 Bres(XtNscrollBar, XtCScrollBar, misc.scrollbar, False), 420 Bres(XtNscrollKey, XtCScrollCond, screen.scrollkey, False), 421 Bres(XtNscrollTtyOutput, XtCScrollCond, screen.scrollttyoutput, True), 422 Bres(XtNselectToClipboard, XtCSelectToClipboard, 423 screen.selectToClipboard, False), 424 Bres(XtNsignalInhibit, XtCSignalInhibit, misc.signalInhibit, False), 425 Bres(XtNtiteInhibit, XtCTiteInhibit, misc.titeInhibit, False), 426 Bres(XtNtiXtraScroll, XtCTiXtraScroll, misc.tiXtraScroll, False), 427 Bres(XtNtrimSelection, XtCTrimSelection, screen.trim_selection, False), 428 Bres(XtNunderLine, XtCUnderLine, screen.underline, True), 429 Bres(XtNvisualBell, XtCVisualBell, screen.visualbell, False), 430 431 Ires(XtNbellSuppressTime, XtCBellSuppressTime, screen.bellSuppressTime, BELLSUPPRESSMSEC), 432 Ires(XtNfontWarnings, XtCFontWarnings, misc.fontWarnings, fwResource), 433 Ires(XtNinternalBorder, XtCBorderWidth, screen.border, DEFBORDER), 434 Ires(XtNlimitResize, XtCLimitResize, misc.limit_resize, 1), 435 Ires(XtNmultiClickTime, XtCMultiClickTime, screen.multiClickTime, MULTICLICKTIME), 436 Ires(XtNnMarginBell, XtCColumn, screen.nmarginbell, N_MARGINBELL), 437 Ires(XtNpointerMode, XtCPointerMode, screen.pointer_mode, DEF_POINTER_MODE), 438 Ires(XtNprinterControlMode, XtCPrinterControlMode, 439 screen.printer_controlmode, 0), 440 Ires(XtNtitleModes, XtCTitleModes, screen.title_modes, DEF_TITLE_MODES), 441 Ires(XtNvisualBellDelay, XtCVisualBellDelay, screen.visualBellDelay, 100), 442 Ires(XtNsaveLines, XtCSaveLines, screen.savelines, SAVELINES), 443 Ires(XtNscrollBarBorder, XtCScrollBarBorder, screen.scrollBarBorder, 1), 444 Ires(XtNscrollLines, XtCScrollLines, screen.scrolllines, SCROLLLINES), 445 446 Sres(XtNinitialFont, XtCInitialFont, screen.initial_font, NULL), 447 Sres(XtNfont1, XtCFont1, screen.MenuFontName(fontMenu_font1), NULL), 448 Sres(XtNfont2, XtCFont2, screen.MenuFontName(fontMenu_font2), NULL), 449 Sres(XtNfont3, XtCFont3, screen.MenuFontName(fontMenu_font3), NULL), 450 Sres(XtNfont4, XtCFont4, screen.MenuFontName(fontMenu_font4), NULL), 451 Sres(XtNfont5, XtCFont5, screen.MenuFontName(fontMenu_font5), NULL), 452 Sres(XtNfont6, XtCFont6, screen.MenuFontName(fontMenu_font6), NULL), 453 454 Sres(XtNanswerbackString, XtCAnswerbackString, screen.answer_back, ""), 455 Sres(XtNboldFont, XtCBoldFont, misc.default_font.f_b, DEFBOLDFONT), 456 Sres(XtNcharClass, XtCCharClass, screen.charClass, NULL), 457 Sres(XtNdecTerminalID, XtCDecTerminalID, screen.term_id, DFT_DECID), 458 Sres(XtNdefaultString, XtCDefaultString, screen.default_string, "#"), 459 Sres(XtNdisallowedColorOps, XtCDisallowedColorOps, 460 screen.disallowedColorOps, DEF_DISALLOWED_COLOR), 461 Sres(XtNdisallowedFontOps, XtCDisallowedFontOps, 462 screen.disallowedFontOps, DEF_DISALLOWED_FONT), 463 Sres(XtNdisallowedTcapOps, XtCDisallowedTcapOps, 464 screen.disallowedTcapOps, DEF_DISALLOWED_TCAP), 465 Sres(XtNdisallowedWindowOps, XtCDisallowedWindowOps, 466 screen.disallowedWinOps, DEF_DISALLOWED_WINDOW), 467 Sres(XtNeightBitSelectTypes, XtCEightBitSelectTypes, 468 screen.eightbit_select_types, NULL), 469 Sres(XtNfont, XtCFont, misc.default_font.f_n, DEFFONT), 470 Sres(XtNgeometry, XtCGeometry, misc.geo_metry, NULL), 471 Sres(XtNkeyboardDialect, XtCKeyboardDialect, screen.keyboard_dialect, DFT_KBD_DIALECT), 472 Sres(XtNprinterCommand, XtCPrinterCommand, screen.printer_command, ""), 473 Sres(XtNtekGeometry, XtCGeometry, misc.T_geometry, NULL), 474 475 Tres(XtNcursorColor, XtCCursorColor, TEXT_CURSOR, XtDefaultForeground), 476 Tres(XtNforeground, XtCForeground, TEXT_FG, XtDefaultForeground), 477 Tres(XtNpointerColor, XtCPointerColor, MOUSE_FG, XtDefaultForeground), 478 Tres(XtNbackground, XtCBackground, TEXT_BG, XtDefaultBackground), 479 Tres(XtNpointerColorBackground, XtCBackground, MOUSE_BG, XtDefaultBackground), 480 481 {XtNresizeGravity, XtCResizeGravity, XtRGravity, sizeof(XtGravity), 482 XtOffsetOf(XtermWidgetRec, misc.resizeGravity), 483 XtRImmediate, (XtPointer) SouthWestGravity}, 484 485 {XtNpointerShape, XtCCursor, XtRCursor, sizeof(Cursor), 486 XtOffsetOf(XtermWidgetRec, screen.pointer_cursor), 487 XtRString, (XtPointer) "xterm"}, 488 489#ifdef ALLOWLOGGING 490 Bres(XtNlogInhibit, XtCLogInhibit, misc.logInhibit, False), 491 Bres(XtNlogging, XtCLogging, misc.log_on, False), 492 Sres(XtNlogFile, XtCLogfile, screen.logfile, NULL), 493#endif 494 495#ifndef NO_ACTIVE_ICON 496 Bres("activeIcon", "ActiveIcon", misc.active_icon, False), 497 Ires("iconBorderWidth", XtCBorderWidth, misc.icon_border_width, 2), 498 Sres("iconFont", "IconFont", screen.icon_fontname, "nil2"), 499 Cres("iconBorderColor", XtCBorderColor, misc.icon_border_pixel, XtDefaultBackground), 500#endif /* NO_ACTIVE_ICON */ 501 502#if OPT_BLINK_CURS 503 Bres(XtNcursorBlink, XtCCursorBlink, screen.cursor_blink, False), 504#endif 505 Bres(XtNcursorUnderline, XtCCursorUnderline, screen.cursor_underline, False), 506 507#if OPT_BLINK_TEXT 508 Bres(XtNshowBlinkAsBold, XtCCursorBlink, screen.blink_as_bold, DEFBLINKASBOLD), 509#endif 510 511#if OPT_BLINK_CURS || OPT_BLINK_TEXT 512 Ires(XtNcursorOnTime, XtCCursorOnTime, screen.blink_on, 600), 513 Ires(XtNcursorOffTime, XtCCursorOffTime, screen.blink_off, 300), 514#endif 515 516#if OPT_BOX_CHARS 517 Bres(XtNforceBoxChars, XtCForceBoxChars, screen.force_box_chars, False), 518 Bres(XtNforcePackedFont, XtCForcePackedFont, screen.force_packed, True), 519 Bres(XtNshowMissingGlyphs, XtCShowMissingGlyphs, screen.force_all_chars, False), 520#endif 521 522#if OPT_BROKEN_OSC 523 Bres(XtNbrokenLinuxOSC, XtCBrokenLinuxOSC, screen.brokenLinuxOSC, True), 524#endif 525 526#if OPT_BROKEN_ST 527 Bres(XtNbrokenStringTerm, XtCBrokenStringTerm, screen.brokenStringTerm, True), 528#endif 529 530#if OPT_C1_PRINT 531 Bres(XtNallowC1Printable, XtCAllowC1Printable, screen.c1_printable, False), 532#endif 533 534#if OPT_CLIP_BOLD 535 Bres(XtNuseClipping, XtCUseClipping, screen.use_clipping, True), 536#endif 537 538#if OPT_DEC_CHRSET 539 Bres(XtNfontDoublesize, XtCFontDoublesize, screen.font_doublesize, True), 540 Ires(XtNcacheDoublesize, XtCCacheDoublesize, screen.cache_doublesize, NUM_CHRSET), 541#endif 542 543#if OPT_HIGHLIGHT_COLOR 544 Tres(XtNhighlightColor, XtCHighlightColor, HIGHLIGHT_BG, XtDefaultForeground), 545 Tres(XtNhighlightTextColor, XtCHighlightTextColor, HIGHLIGHT_FG, XtDefaultBackground), 546 Bres(XtNhighlightReverse, XtCHighlightReverse, screen.hilite_reverse, True), 547 Bres(XtNhighlightColorMode, XtCHighlightColorMode, screen.hilite_color, Maybe), 548#endif /* OPT_HIGHLIGHT_COLOR */ 549 550#if OPT_INPUT_METHOD 551 Bres(XtNopenIm, XtCOpenIm, misc.open_im, True), 552 Sres(XtNinputMethod, XtCInputMethod, misc.input_method, NULL), 553 Sres(XtNpreeditType, XtCPreeditType, misc.preedit_type, 554 "OverTheSpot,Root"), 555 Ires(XtNretryInputMethod, XtCRetryInputMethod, misc.retry_im, 3), 556#endif 557 558#if OPT_ISO_COLORS 559 Bres(XtNboldColors, XtCColorMode, screen.boldColors, True), 560 Ires(XtNveryBoldColors, XtCVeryBoldColors, screen.veryBoldColors, 0), 561 Bres(XtNcolorMode, XtCColorMode, screen.colorMode, DFT_COLORMODE), 562 563 Bres(XtNcolorAttrMode, XtCColorAttrMode, screen.colorAttrMode, False), 564 Bres(XtNcolorBDMode, XtCColorAttrMode, screen.colorBDMode, False), 565 Bres(XtNcolorBLMode, XtCColorAttrMode, screen.colorBLMode, False), 566 Bres(XtNcolorRVMode, XtCColorAttrMode, screen.colorRVMode, False), 567 Bres(XtNcolorULMode, XtCColorAttrMode, screen.colorULMode, False), 568 Bres(XtNitalicULMode, XtCColorAttrMode, screen.italicULMode, False), 569 570 COLOR_RES("0", screen.Acolors[COLOR_0], DFT_COLOR("black")), 571 COLOR_RES("1", screen.Acolors[COLOR_1], DFT_COLOR("red3")), 572 COLOR_RES("2", screen.Acolors[COLOR_2], DFT_COLOR("green3")), 573 COLOR_RES("3", screen.Acolors[COLOR_3], DFT_COLOR("yellow3")), 574 COLOR_RES("4", screen.Acolors[COLOR_4], DFT_COLOR(DEF_COLOR4)), 575 COLOR_RES("5", screen.Acolors[COLOR_5], DFT_COLOR("magenta3")), 576 COLOR_RES("6", screen.Acolors[COLOR_6], DFT_COLOR("cyan3")), 577 COLOR_RES("7", screen.Acolors[COLOR_7], DFT_COLOR("gray90")), 578 COLOR_RES("8", screen.Acolors[COLOR_8], DFT_COLOR("gray50")), 579 COLOR_RES("9", screen.Acolors[COLOR_9], DFT_COLOR("red")), 580 COLOR_RES("10", screen.Acolors[COLOR_10], DFT_COLOR("green")), 581 COLOR_RES("11", screen.Acolors[COLOR_11], DFT_COLOR("yellow")), 582 COLOR_RES("12", screen.Acolors[COLOR_12], DFT_COLOR(DEF_COLOR12)), 583 COLOR_RES("13", screen.Acolors[COLOR_13], DFT_COLOR("magenta")), 584 COLOR_RES("14", screen.Acolors[COLOR_14], DFT_COLOR("cyan")), 585 COLOR_RES("15", screen.Acolors[COLOR_15], DFT_COLOR("white")), 586 COLOR_RES("BD", screen.Acolors[COLOR_BD], DFT_COLOR(XtDefaultForeground)), 587 COLOR_RES("BL", screen.Acolors[COLOR_BL], DFT_COLOR(XtDefaultForeground)), 588 COLOR_RES("UL", screen.Acolors[COLOR_UL], DFT_COLOR(XtDefaultForeground)), 589 COLOR_RES("RV", screen.Acolors[COLOR_RV], DFT_COLOR(XtDefaultForeground)), 590 591#if !OPT_COLOR_RES2 592#if OPT_256_COLORS 593# include <256colres.h> 594#elif OPT_88_COLORS 595# include <88colres.h> 596#endif 597#endif /* !OPT_COLOR_RES2 */ 598 599#endif /* OPT_ISO_COLORS */ 600 601 CLICK_RES("2", screen.onClick[1], "word"), 602 CLICK_RES("3", screen.onClick[2], "line"), 603 CLICK_RES("4", screen.onClick[3], 0), 604 CLICK_RES("5", screen.onClick[4], 0), 605 606#if OPT_MOD_FKEYS 607 Ires(XtNmodifyCursorKeys, XtCModifyCursorKeys, 608 keyboard.modify_1st.cursor_keys, 2), 609 Ires(XtNmodifyFunctionKeys, XtCModifyFunctionKeys, 610 keyboard.modify_1st.function_keys, 2), 611 Ires(XtNmodifyKeypadKeys, XtCModifyKeypadKeys, 612 keyboard.modify_1st.keypad_keys, 0), 613 Ires(XtNmodifyOtherKeys, XtCModifyOtherKeys, 614 keyboard.modify_1st.other_keys, 0), 615 Ires(XtNmodifyStringKeys, XtCModifyStringKeys, 616 keyboard.modify_1st.string_keys, 0), 617 Ires(XtNformatOtherKeys, XtCFormatOtherKeys, 618 keyboard.format_keys, 0), 619#endif 620 621#if OPT_NUM_LOCK 622 Bres(XtNalwaysUseMods, XtCAlwaysUseMods, misc.alwaysUseMods, False), 623 Bres(XtNnumLock, XtCNumLock, misc.real_NumLock, True), 624#endif 625 626#if OPT_PRINT_COLORS 627 Ires(XtNprintAttributes, XtCPrintAttributes, screen.print_attributes, 1), 628#endif 629 630#if OPT_SHIFT_FONTS 631 Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True), 632#endif 633 634#if OPT_SUNPC_KBD 635 Ires(XtNctrlFKeys, XtCCtrlFKeys, misc.ctrl_fkeys, 10), 636#endif 637 638#if OPT_TEK4014 639 Bres(XtNtekInhibit, XtCTekInhibit, misc.tekInhibit, False), 640 Bres(XtNtekSmall, XtCTekSmall, misc.tekSmall, False), 641 Bres(XtNtekStartup, XtCTekStartup, misc.TekEmu, False), 642#endif 643 644#if OPT_TOOLBAR 645 Wres(XtNmenuBar, XtCMenuBar, VT100_TB_INFO(menu_bar), 0), 646 Ires(XtNmenuHeight, XtCMenuHeight, VT100_TB_INFO(menu_height), 25), 647#endif 648 649#if OPT_WIDE_CHARS 650 Bres(XtNcjkWidth, XtCCjkWidth, misc.cjk_width, False), 651 Bres(XtNmkWidth, XtCMkWidth, misc.mk_width, False), 652 Bres(XtNutf8Latin1, XtCUtf8Latin1, screen.utf8_latin1, False), 653 Bres(XtNutf8Title, XtCUtf8Title, screen.utf8_title, False), 654 Bres(XtNvt100Graphics, XtCVT100Graphics, screen.vt100_graphics, True), 655 Bres(XtNwideChars, XtCWideChars, screen.wide_chars, False), 656 Ires(XtNcombiningChars, XtCCombiningChars, screen.max_combining, 2), 657 Ires(XtNmkSamplePass, XtCMkSamplePass, misc.mk_samplepass, 256), 658 Ires(XtNmkSampleSize, XtCMkSampleSize, misc.mk_samplesize, 1024), 659 Ires(XtNutf8, XtCUtf8, screen.utf8_mode, uDefault), 660 Sres(XtNwideBoldFont, XtCWideBoldFont, misc.default_font.f_wb, DEFWIDEBOLDFONT), 661 Sres(XtNwideFont, XtCWideFont, misc.default_font.f_w, DEFWIDEFONT), 662 Sres(XtNutf8SelectTypes, XtCUtf8SelectTypes, screen.utf8_select_types, NULL), 663#endif 664 665#if OPT_LUIT_PROG 666 Sres(XtNlocale, XtCLocale, misc.locale_str, "medium"), 667 Sres(XtNlocaleFilter, XtCLocaleFilter, misc.localefilter, DEFLOCALEFILTER), 668#endif 669 670#if OPT_INPUT_METHOD 671 Sres(XtNximFont, XtCXimFont, misc.f_x, DEFXIMFONT), 672#endif 673 674#if OPT_SCROLL_LOCK 675 Bres(XtNallowScrollLock, XtCAllowScrollLock, screen.allowScrollLock0, False), 676#endif 677 678#if OPT_XMC_GLITCH 679 Bres(XtNxmcInline, XtCXmcInline, screen.xmc_inline, False), 680 Bres(XtNxmcMoveSGR, XtCXmcMoveSGR, screen.move_sgr_ok, True), 681 Ires(XtNxmcAttributes, XtCXmcAttributes, screen.xmc_attributes, 1), 682 Ires(XtNxmcGlitch, XtCXmcGlitch, screen.xmc_glitch, 0), 683#endif 684 685#ifdef SCROLLBAR_RIGHT 686 Bres(XtNrightScrollBar, XtCRightScrollBar, misc.useRight, False), 687#endif 688 689#if OPT_RENDERFONT 690#define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0") 691 RES_FACESIZE(1), 692 RES_FACESIZE(2), 693 RES_FACESIZE(3), 694 RES_FACESIZE(4), 695 RES_FACESIZE(5), 696 RES_FACESIZE(6), 697 Dres(XtNfaceSize, XtCFaceSize, misc.face_size[0], DEFFACESIZE), 698 Sres(XtNfaceName, XtCFaceName, misc.face_name, DEFFACENAME), 699 Sres(XtNfaceNameDoublesize, XtCFaceNameDoublesize, misc.face_wide_name, DEFFACENAME), 700 Sres(XtNrenderFont, XtCRenderFont, misc.render_font_s, "default"), 701#endif 702}; 703 704static Boolean VTSetValues(Widget cur, Widget request, Widget new_arg, 705 ArgList args, Cardinal *num_args); 706static void VTClassInit(void); 707static void VTDestroy(Widget w); 708static void VTExpose(Widget w, XEvent * event, Region region); 709static void VTInitialize(Widget wrequest, Widget new_arg, ArgList args, 710 Cardinal *num_args); 711static void VTRealize(Widget w, XtValueMask * valuemask, 712 XSetWindowAttributes * values); 713static void VTResize(Widget w); 714 715#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 716static void VTInitI18N(XtermWidget); 717#endif 718 719#ifdef VMS 720globaldef { 721 "xtermclassrec" 722} noshare 723 724#else 725static 726#endif /* VMS */ 727WidgetClassRec xtermClassRec = 728{ 729 { 730 /* core_class fields */ 731 (WidgetClass) & widgetClassRec, /* superclass */ 732 "VT100", /* class_name */ 733 sizeof(XtermWidgetRec), /* widget_size */ 734 VTClassInit, /* class_initialize */ 735 NULL, /* class_part_initialize */ 736 False, /* class_inited */ 737 VTInitialize, /* initialize */ 738 NULL, /* initialize_hook */ 739 VTRealize, /* realize */ 740 actionsList, /* actions */ 741 XtNumber(actionsList), /* num_actions */ 742 xterm_resources, /* resources */ 743 XtNumber(xterm_resources), /* num_resources */ 744 NULLQUARK, /* xrm_class */ 745 True, /* compress_motion */ 746 False, /* compress_exposure */ 747 True, /* compress_enterleave */ 748 False, /* visible_interest */ 749 VTDestroy, /* destroy */ 750 VTResize, /* resize */ 751 VTExpose, /* expose */ 752 VTSetValues, /* set_values */ 753 NULL, /* set_values_hook */ 754 XtInheritSetValuesAlmost, /* set_values_almost */ 755 NULL, /* get_values_hook */ 756 NULL, /* accept_focus */ 757 XtVersion, /* version */ 758 NULL, /* callback_offsets */ 759 0, /* tm_table */ 760 XtInheritQueryGeometry, /* query_geometry */ 761 XtInheritDisplayAccelerator, /* display_accelerator */ 762 NULL /* extension */ 763 } 764}; 765 766#ifdef VMS 767globaldef { 768 "xtermwidgetclass" 769} 770noshare 771#endif /* VMS */ 772WidgetClass xtermWidgetClass = (WidgetClass) & xtermClassRec; 773 774/* 775 * Add input-actions for widgets that are overlooked (scrollbar and toolbar): 776 * 777 * a) Sometimes the scrollbar passes through translations, sometimes it 778 * doesn't. We add the KeyPress translations here, just to be sure. 779 * b) In the normal (non-toolbar) configuration, the xterm widget covers 780 * almost all of the window. With a toolbar, there's a relatively 781 * large area that the user would expect to enter keystrokes since the 782 * program can get the focus. 783 */ 784void 785xtermAddInput(Widget w) 786{ 787 /* *INDENT-OFF* */ 788 XtActionsRec input_actions[] = { 789 { "insert", HandleKeyPressed }, /* alias */ 790 { "insert-eight-bit", HandleEightBitKeyPressed }, 791 { "insert-seven-bit", HandleKeyPressed }, 792 { "secure", HandleSecure }, 793 { "string", HandleStringEvent }, 794 { "scroll-back", HandleScrollBack }, 795 { "scroll-forw", HandleScrollForward }, 796 { "select-cursor-end", HandleKeyboardSelectEnd }, 797 { "select-cursor-extend", HandleKeyboardSelectExtend }, 798 { "select-cursor-start", HandleKeyboardSelectStart }, 799 { "insert-selection", HandleInsertSelection }, 800 { "select-start", HandleSelectStart }, 801 { "select-extend", HandleSelectExtend }, 802 { "start-extend", HandleStartExtend }, 803 { "select-end", HandleSelectEnd }, 804 { "clear-saved-lines", HandleClearSavedLines }, 805 { "popup-menu", HandlePopupMenu }, 806 { "bell", HandleBell }, 807 { "ignore", HandleIgnore }, 808#if OPT_DABBREV 809 { "dabbrev-expand", HandleDabbrevExpand }, 810#endif 811#if OPT_MAXIMIZE 812 { "fullscreen", HandleFullscreen }, 813#endif 814#if OPT_SCROLL_LOCK 815 { "scroll-lock", HandleScrollLock }, 816#endif 817#if OPT_SHIFT_FONTS 818 { "larger-vt-font", HandleLargerFont }, 819 { "smaller-vt-font", HandleSmallerFont }, 820#endif 821 }; 822 /* *INDENT-ON* */ 823 824 TRACE_TRANS("BEFORE", w); 825 XtAppAddActions(app_con, input_actions, XtNumber(input_actions)); 826 XtAugmentTranslations(w, XtParseTranslationTable(defaultTranslations)); 827 TRACE_TRANS("AFTER:", w); 828 829#if OPT_EXTRA_PASTE 830 if (term && term->keyboard.extra_translations) 831 XtOverrideTranslations((Widget) term, XtParseTranslationTable(term->keyboard.extra_translations)); 832#endif 833} 834 835#if OPT_ISO_COLORS 836#ifdef EXP_BOGUS_FG 837static Bool 838CheckBogusForeground(TScreen * screen, const char *tag) 839{ 840 int row = -1, col = -1, pass; 841 Bool isClear = True; 842 843 (void) tag; 844 for (pass = 0; pass < 2; ++pass) { 845 row = screen->cur_row; 846 for (; isClear && (row <= screen->max_row); ++row) { 847 LineData *ld = getLineData(screen, row)->; 848 849 if (ld != 0) { 850 Char *attribs = ld->attribs; 851 852 col = (row == screen->cur_row) ? screen->cur_col : 0; 853 for (; isClear && (col <= screen->max_col); ++col) { 854 unsigned flags = attribs[col]; 855 if (pass) { 856 flags &= ~FG_COLOR; 857 attribs[col] = (Char) flags; 858 } else if ((flags & BG_COLOR)) { 859 isClear = False; 860 } else if ((flags & FG_COLOR)) { 861 unsigned ch = ld->charData[col]; 862 isClear = ((ch == ' ') || (ch == 0)); 863 } else { 864 isClear = False; 865 } 866 } 867 } 868 } 869 } 870 TRACE(("%s checked %d,%d to %d,%d %s pass %d\n", 871 tag, screen->cur_row, screen->cur_col, 872 row, col, 873 isClear && pass ? "cleared" : "unchanged", 874 pass)); 875 876 return isClear; 877} 878#endif 879 880/* 881 * The terminal's foreground and background colors are set via two mechanisms: 882 * text (cur_foreground, cur_background values that are passed down to 883 * XDrawImageString and XDrawString) 884 * area (X11 graphics context used in XClearArea and XFillRectangle) 885 */ 886void 887SGR_Foreground(XtermWidget xw, int color) 888{ 889 TScreen *screen = TScreenOf(xw); 890 Pixel fg; 891 892 if (color >= 0) { 893 UIntSet(xw->flags, FG_COLOR); 894 } else { 895 UIntClr(xw->flags, FG_COLOR); 896 } 897 fg = getXtermForeground(xw, xw->flags, color); 898 xw->cur_foreground = color; 899 900 setCgsFore(xw, WhichVWin(screen), gcNorm, fg); 901 setCgsBack(xw, WhichVWin(screen), gcNormReverse, fg); 902 903 setCgsFore(xw, WhichVWin(screen), gcBold, fg); 904 setCgsBack(xw, WhichVWin(screen), gcBoldReverse, fg); 905 906#ifdef EXP_BOGUS_FG 907 /* 908 * If we've just turned off the foreground color, check for blank cells 909 * which have no background color, but do have foreground color. This 910 * could happen due to setting the foreground color just before scrolling. 911 * 912 * Those cells look uncolored, but will confuse ShowCursor(), which looks 913 * for the colors in the current cell, and will see the foreground color. 914 * In that case, remove the foreground color from the blank cells. 915 */ 916 if (color < 0) { 917 CheckBogusForeground(screen, "SGR_Foreground"); 918 } 919#endif 920} 921 922void 923SGR_Background(XtermWidget xw, int color) 924{ 925 TScreen *screen = TScreenOf(xw); 926 Pixel bg; 927 928 /* 929 * An indexing operation may have set screen->scroll_amt, which would 930 * normally result in calling FlushScroll() in WriteText(). However, 931 * if we're changing the background color now, then the new value 932 * should not apply to the pending blank lines. 933 */ 934 if (screen->scroll_amt && (color != xw->cur_background)) 935 FlushScroll(xw); 936 937 if (color >= 0) { 938 UIntSet(xw->flags, BG_COLOR); 939 } else { 940 UIntClr(xw->flags, BG_COLOR); 941 } 942 bg = getXtermBackground(xw, xw->flags, color); 943 xw->cur_background = color; 944 945 setCgsBack(xw, WhichVWin(screen), gcNorm, bg); 946 setCgsFore(xw, WhichVWin(screen), gcNormReverse, bg); 947 948 setCgsBack(xw, WhichVWin(screen), gcBold, bg); 949 setCgsFore(xw, WhichVWin(screen), gcBoldReverse, bg); 950} 951 952/* Invoked after updating bold/underline flags, computes the extended color 953 * index to use for foreground. (See also 'extract_fg()'). 954 */ 955static void 956setExtendedFG(XtermWidget xw) 957{ 958 int fg = xw->sgr_foreground; 959 960 if (TScreenOf(xw)->colorAttrMode 961 || (fg < 0)) { 962 fg = MapToColorMode(fg, TScreenOf(xw), xw->flags); 963 } 964 965 /* This implements the IBM PC-style convention of 8-colors, with one 966 * bit for bold, thus mapping the 0-7 codes to 8-15. It won't make 967 * much sense for 16-color applications, but we keep it to retain 968 * compatiblity with ANSI-color applications. 969 */ 970#if OPT_PC_COLORS /* XXXJTL should be settable at runtime (resource or OSC?) */ 971 if (TScreenOf(xw)->boldColors 972 && (!xw->sgr_extended) 973 && (fg >= 0) 974 && (fg < 8) 975 && (xw->flags & BOLD)) 976 fg |= 8; 977#endif 978 979 SGR_Foreground(xw, fg); 980} 981 982/* Invoked after updating inverse flag, computes the extended color 983 * index to use for background. (See also 'extract_bg()'). 984 */ 985static void 986setExtendedBG(XtermWidget xw) 987{ 988 int bg = xw->sgr_background; 989 990 if (TScreenOf(xw)->colorAttrMode 991 || (bg < 0)) { 992 if (TScreenOf(xw)->colorRVMode && (xw->flags & INVERSE)) 993 bg = COLOR_RV; 994 } 995 996 SGR_Background(xw, bg); 997} 998 999static void 1000reset_SGR_Foreground(XtermWidget xw) 1001{ 1002 xw->sgr_foreground = -1; 1003 xw->sgr_extended = False; 1004 setExtendedFG(xw); 1005} 1006 1007static void 1008reset_SGR_Background(XtermWidget xw) 1009{ 1010 xw->sgr_background = -1; 1011 setExtendedBG(xw); 1012} 1013 1014static void 1015reset_SGR_Colors(XtermWidget xw) 1016{ 1017 reset_SGR_Foreground(xw); 1018 reset_SGR_Background(xw); 1019} 1020#endif /* OPT_ISO_COLORS */ 1021 1022void 1023resetCharsets(TScreen * screen) 1024{ 1025 TRACE(("resetCharsets\n")); 1026 1027 screen->gsets[0] = 'B'; /* ASCII_G */ 1028 screen->gsets[1] = 'B'; /* ASCII_G */ 1029 screen->gsets[2] = 'B'; /* ASCII_G */ 1030 screen->gsets[3] = 'B'; /* ASCII_G */ 1031 1032 screen->curgl = 0; /* G0 => GL. */ 1033 screen->curgr = 2; /* G2 => GR. */ 1034 screen->curss = 0; /* No single shift. */ 1035 1036#if OPT_VT52_MODE 1037 if (screen->vtXX_level == 0) 1038 screen->gsets[1] = '0'; /* Graphics */ 1039#endif 1040} 1041 1042/* 1043 * VT300 and up support three ANSI conformance levels, defined according to 1044 * the dpANSI X3.134.1 standard. DEC's manuals equate levels 1 and 2, and 1045 * are unclear. This code is written based on the manuals. 1046 */ 1047static void 1048set_ansi_conformance(TScreen * screen, int level) 1049{ 1050 TRACE(("set_ansi_conformance(%d) terminal_id %d, ansi_level %d\n", 1051 level, 1052 screen->terminal_id, 1053 screen->ansi_level)); 1054 if (screen->vtXX_level >= 3) { 1055 switch (screen->ansi_level = level) { 1056 case 1: 1057 /* FALLTHRU */ 1058 case 2: 1059 screen->gsets[0] = 'B'; /* G0 is ASCII */ 1060 screen->gsets[1] = 'B'; /* G1 is ISO Latin-1 (FIXME) */ 1061 screen->curgl = 0; 1062 screen->curgr = 1; 1063 break; 1064 case 3: 1065 screen->gsets[0] = 'B'; /* G0 is ASCII */ 1066 screen->curgl = 0; 1067 break; 1068 } 1069 } 1070} 1071 1072/* 1073 * Set scrolling margins. VTxxx terminals require that the top/bottom are 1074 * different, so we have at least two lines in the scrolling region. 1075 */ 1076void 1077set_tb_margins(TScreen * screen, int top, int bottom) 1078{ 1079 TRACE(("set_tb_margins %d..%d, prior %d..%d\n", 1080 top, bottom, 1081 screen->top_marg, 1082 screen->bot_marg)); 1083 if (bottom > top) { 1084 screen->top_marg = top; 1085 screen->bot_marg = bottom; 1086 } 1087 if (screen->top_marg > screen->max_row) 1088 screen->top_marg = screen->max_row; 1089 if (screen->bot_marg > screen->max_row) 1090 screen->bot_marg = screen->max_row; 1091} 1092 1093void 1094set_max_col(TScreen * screen, int cols) 1095{ 1096 TRACE(("set_max_col %d, prior %d\n", cols, screen->max_col)); 1097 if (cols < 0) 1098 cols = 0; 1099 screen->max_col = cols; 1100} 1101 1102void 1103set_max_row(TScreen * screen, int rows) 1104{ 1105 TRACE(("set_max_row %d, prior %d\n", rows, screen->max_row)); 1106 if (rows < 0) 1107 rows = 0; 1108 screen->max_row = rows; 1109} 1110 1111#if OPT_MOD_FKEYS 1112static void 1113set_mod_fkeys(XtermWidget xw, int which, int what, Bool enabled) 1114{ 1115#define SET_MOD_FKEYS(field) \ 1116 xw->keyboard.modify_now.field = ((what == DEFAULT) && enabled) \ 1117 ? xw->keyboard.modify_1st.field \ 1118 : what; \ 1119 TRACE(("set modify_now.%s to %d\n", #field, \ 1120 xw->keyboard.modify_now.field)); 1121 1122 switch (which) { 1123 case 1: 1124 SET_MOD_FKEYS(cursor_keys); 1125 break; 1126 case 2: 1127 SET_MOD_FKEYS(function_keys); 1128 break; 1129 case 3: 1130 SET_MOD_FKEYS(keypad_keys); 1131 break; 1132 case 4: 1133 SET_MOD_FKEYS(other_keys); 1134 break; 1135 case 5: 1136 SET_MOD_FKEYS(string_keys); 1137 break; 1138 } 1139} 1140#endif /* OPT_MOD_FKEYS */ 1141 1142#if OPT_TRACE 1143#define WHICH_TABLE(name) if (table == name) result = #name 1144static const char * 1145which_table(Const PARSE_T * table) 1146{ 1147 const char *result = "?"; 1148 /* *INDENT-OFF* */ 1149 WHICH_TABLE (ansi_table); 1150 else WHICH_TABLE (cigtable); 1151 else WHICH_TABLE (csi2_table); 1152 else WHICH_TABLE (csi_ex_table); 1153 else WHICH_TABLE (csi_quo_table); 1154 else WHICH_TABLE (csi_table); 1155 else WHICH_TABLE (dec2_table); 1156 else WHICH_TABLE (dec3_table); 1157 else WHICH_TABLE (dec_table); 1158 else WHICH_TABLE (eigtable); 1159 else WHICH_TABLE (esc_sp_table); 1160 else WHICH_TABLE (esc_table); 1161 else WHICH_TABLE (scrtable); 1162 else WHICH_TABLE (scs96table); 1163 else WHICH_TABLE (scstable); 1164 else WHICH_TABLE (sos_table); 1165#if OPT_BLINK_CURS 1166 else WHICH_TABLE (csi_sp_table); 1167#endif 1168#if OPT_DEC_LOCATOR 1169 else WHICH_TABLE (csi_tick_table); 1170#endif 1171#if OPT_DEC_RECTOPS 1172 else WHICH_TABLE (csi_dollar_table); 1173 else WHICH_TABLE (csi_star_table); 1174 else WHICH_TABLE (csi_dec_dollar_table); 1175#endif 1176#if OPT_WIDE_CHARS 1177 else WHICH_TABLE (esc_pct_table); 1178#endif 1179#if OPT_VT52_MODE 1180 else WHICH_TABLE (vt52_table); 1181 else WHICH_TABLE (vt52_esc_table); 1182 else WHICH_TABLE (vt52_ignore_table); 1183#endif 1184 /* *INDENT-ON* */ 1185 1186 return result; 1187} 1188#endif 1189 1190 /* allocate larger buffer if needed/possible */ 1191#define SafeAlloc(type, area, used, size) \ 1192 type *new_string = area; \ 1193 size_t new_length = size; \ 1194 if (new_length == 0) { \ 1195 new_length = 256; \ 1196 new_string = TypeMallocN(type, new_length); \ 1197 } else if (used+1 >= new_length) { \ 1198 new_length = size * 2; \ 1199 new_string = TypeMallocN(type, new_length); \ 1200 if (new_string != 0 \ 1201 && area != 0 \ 1202 && used != 0) \ 1203 memcpy(new_string, area, used * sizeof(type)); \ 1204 } 1205 1206#define WriteNow() { \ 1207 unsigned single = 0; \ 1208 \ 1209 if (screen->curss) { \ 1210 dotext(xw, \ 1211 screen->gsets[(int) (screen->curss)], \ 1212 sp->print_area, \ 1213 (Cardinal) 1); \ 1214 screen->curss = 0; \ 1215 single++; \ 1216 } \ 1217 if (sp->print_used > single) { \ 1218 dotext(xw, \ 1219 screen->gsets[(int) (screen->curgl)], \ 1220 sp->print_area + single, \ 1221 (Cardinal) (sp->print_used - single)); \ 1222 } \ 1223 sp->print_used = 0; \ 1224 } \ 1225 1226struct ParseState { 1227#if OPT_VT52_MODE 1228 Bool vt52_cup; 1229#endif 1230 Const PARSE_T *groundtable; 1231 Const PARSE_T *parsestate; 1232 int scstype; 1233 int scssize; 1234 Bool private_function; /* distinguish private-mode from standard */ 1235 int string_mode; /* nonzero iff we're processing a string */ 1236 int lastchar; /* positive iff we had a graphic character */ 1237 int nextstate; 1238#if OPT_WIDE_CHARS 1239 int last_was_wide; 1240#endif 1241 /* Buffer for processing printable text */ 1242 IChar *print_area; 1243 size_t print_size; 1244 size_t print_used; 1245 /* Buffer for processing strings (e.g., OSC ... ST) */ 1246 Char *string_area; 1247 size_t string_size; 1248 size_t string_used; 1249}; 1250 1251static struct ParseState myState; 1252 1253static void 1254init_groundtable(TScreen * screen, struct ParseState *sp) 1255{ 1256 (void) screen; 1257 1258#if OPT_VT52_MODE 1259 if (!(screen->vtXX_level)) { 1260 sp->groundtable = vt52_table; 1261 } else if (screen->terminal_id >= 100) 1262#endif 1263 { 1264 sp->groundtable = ansi_table; 1265 } 1266} 1267 1268static void 1269select_charset(struct ParseState *sp, int type, int size) 1270{ 1271 TRACE(("select_charset %#x %d\n", type, size)); 1272 sp->scstype = type; 1273 sp->scssize = size; 1274 if (size == 94) { 1275 sp->parsestate = scstable; 1276 } else { 1277 sp->parsestate = scs96table; 1278 } 1279} 1280 1281static int 1282zero_if_default(int which) 1283{ 1284 int result = (nparam > which) ? param[which] : 0; 1285 if (result <= 0) 1286 result = 0; 1287 return result; 1288} 1289 1290static int 1291one_if_default(int which) 1292{ 1293 int result = (nparam > which) ? param[which] : 0; 1294 if (result <= 0) 1295 result = 1; 1296 return result; 1297} 1298 1299#if OPT_C1_PRINT || OPT_WIDE_CHARS 1300#define ParseSOS(screen) ((screen)->c1_printable == 0) 1301#else 1302#define ParseSOS(screen) 0 1303#endif 1304 1305#define ResetState(sp) (sp)->parsestate = (sp)->groundtable 1306 1307static void 1308illegal_parse(XtermWidget xw, unsigned c, struct ParseState *sp) 1309{ 1310 ResetState(sp); 1311 sp->nextstate = sp->parsestate[E2A(c)]; 1312 Bell(xw, XkbBI_MinorError, 0); 1313} 1314 1315static Boolean 1316doparsing(XtermWidget xw, unsigned c, struct ParseState *sp) 1317{ 1318 TScreen *screen = TScreenOf(xw); 1319 int row; 1320 int col; 1321 int top; 1322 int bot; 1323 int count; 1324 int laststate; 1325 int thischar = -1; 1326 XTermRect myRect; 1327 1328 do { 1329#if OPT_WIDE_CHARS 1330 int this_is_wide = 0; 1331 1332 /* 1333 * Handle zero-width combining characters. Make it faster by noting 1334 * that according to the Unicode charts, the majority of Western 1335 * character sets do not use this feature. There are some unassigned 1336 * codes at 0x242, but no zero-width characters until past 0x300. 1337 */ 1338 if (c >= 0x300 && screen->wide_chars 1339 && my_wcwidth((int) c) == 0 1340 && !isWideControl(c)) { 1341 int prev, precomposed; 1342 1343 WriteNow(); 1344 1345 prev = (int) XTERM_CELL(screen->last_written_row, 1346 screen->last_written_col); 1347 precomposed = do_precomposition(prev, (int) c); 1348 TRACE(("do_precomposition (U+%04X [%d], U+%04X [%d]) -> U+%04X [%d]\n", 1349 prev, my_wcwidth(prev), 1350 (int) c, my_wcwidth((int) c), 1351 precomposed, my_wcwidth(precomposed))); 1352 1353 /* substitute combined character with precomposed character 1354 * only if it does not change the width of the base character 1355 */ 1356 if (precomposed != -1 && my_wcwidth(precomposed) == my_wcwidth(prev)) { 1357 putXtermCell(screen, 1358 screen->last_written_row, 1359 screen->last_written_col, precomposed); 1360 } else { 1361 addXtermCombining(screen, 1362 screen->last_written_row, 1363 screen->last_written_col, c); 1364 } 1365 1366 if (!screen->scroll_amt) 1367 ScrnUpdate(xw, 1368 screen->last_written_row, 1369 screen->last_written_col, 1, 1, 1); 1370 continue; 1371 } 1372#endif 1373 1374 /* Intercept characters for printer controller mode */ 1375 if (screen->printer_controlmode == 2) { 1376 if ((c = (unsigned) xtermPrinterControl(xw, (int) c)) == 0) 1377 continue; 1378 } 1379 1380 /* 1381 * VT52 is a little ugly in the one place it has a parameterized 1382 * control sequence, since the parameter falls after the character 1383 * that denotes the type of sequence. 1384 */ 1385#if OPT_VT52_MODE 1386 if (sp->vt52_cup) { 1387 if (nparam < NPARAM) 1388 param[nparam++] = (int) (c & 0x7f) - 32; 1389 if (nparam < 2) 1390 continue; 1391 sp->vt52_cup = False; 1392 if ((row = param[0]) < 0) 1393 row = 0; 1394 if ((col = param[1]) < 0) 1395 col = 0; 1396 CursorSet(screen, row, col, xw->flags); 1397 sp->parsestate = vt52_table; 1398 param[0] = 0; 1399 param[1] = 0; 1400 continue; 1401 } 1402#endif 1403 1404 laststate = sp->nextstate; 1405 if (c == ANSI_DEL 1406 && sp->parsestate == sp->groundtable 1407 && sp->scssize == 96 1408 && sp->scstype != 0) { 1409 /* 1410 * Handle special case of shifts for 96-character sets by checking 1411 * if we have a DEL. The other special case for SPACE will always 1412 * be printable. 1413 */ 1414 sp->nextstate = CASE_PRINT; 1415 } else 1416#if OPT_WIDE_CHARS 1417 if (c > 255) { 1418 /* 1419 * The parsing tables all have 256 entries. If we're supporting 1420 * wide characters, we handle them by treating them the same as 1421 * printing characters. 1422 */ 1423 if (sp->parsestate == sp->groundtable) { 1424 sp->nextstate = CASE_PRINT; 1425 } else if (sp->parsestate == sos_table) { 1426 c &= 0xffff; 1427 if (c > 255) { 1428 TRACE(("Found code > 255 while in SOS state: %04X\n", c)); 1429 c = '?'; 1430 } 1431 } else { 1432 sp->nextstate = CASE_GROUND_STATE; 1433 } 1434 } else 1435#endif 1436 sp->nextstate = sp->parsestate[E2A(c)]; 1437 1438#if OPT_BROKEN_OSC 1439 /* 1440 * Linux console palette escape sequences start with an OSC, but do 1441 * not terminate correctly. Some scripts do not check before writing 1442 * them, making xterm appear to hang (it's awaiting a valid string 1443 * terminator). Just ignore these if we see them - there's no point 1444 * in emulating bad code. 1445 */ 1446 if (screen->brokenLinuxOSC 1447 && sp->parsestate == sos_table) { 1448 if (sp->string_used) { 1449 switch (sp->string_area[0]) { 1450 case 'P': 1451 if (sp->string_used <= 7) 1452 break; 1453 /* FALLTHRU */ 1454 case 'R': 1455 illegal_parse(xw, c, sp); 1456 TRACE(("Reset to ground state (brokenLinuxOSC)\n")); 1457 break; 1458 } 1459 } 1460 } 1461#endif 1462 1463#if OPT_BROKEN_ST 1464 /* 1465 * Before patch #171, carriage control embedded within an OSC string 1466 * would terminate it. Some (buggy, of course) applications rely on 1467 * this behavior. Accommodate them by allowing one to compile xterm 1468 * and emulate the old behavior. 1469 */ 1470 if (screen->brokenStringTerm 1471 && sp->parsestate == sos_table 1472 && c < 32) { 1473 switch (c) { 1474 case ANSI_EOT: /* FALLTHRU */ 1475 case ANSI_BS: /* FALLTHRU */ 1476 case ANSI_HT: /* FALLTHRU */ 1477 case ANSI_LF: /* FALLTHRU */ 1478 case ANSI_VT: /* FALLTHRU */ 1479 case ANSI_FF: /* FALLTHRU */ 1480 case ANSI_CR: /* FALLTHRU */ 1481 case ANSI_SO: /* FALLTHRU */ 1482 case ANSI_SI: /* FALLTHRU */ 1483 case ANSI_XON: /* FALLTHRU */ 1484 case ANSI_CAN: 1485 illegal_parse(xw, c, sp); 1486 TRACE(("Reset to ground state (brokenStringTerm)\n")); 1487 break; 1488 } 1489 } 1490#endif 1491 1492#if OPT_C1_PRINT 1493 /* 1494 * This is not completely foolproof, but will allow an application 1495 * with values in the C1 range to use them as printable characters, 1496 * provided that they are not intermixed with an escape sequence. 1497 */ 1498 if (screen->c1_printable 1499 && (c >= 128 && c < 160)) { 1500 sp->nextstate = (sp->parsestate == esc_table 1501 ? CASE_ESC_IGNORE 1502 : sp->parsestate[E2A(160)]); 1503 } 1504#endif 1505 1506#if OPT_WIDE_CHARS 1507 /* 1508 * If we have a C1 code and the c1_printable flag is not set, simply 1509 * ignore it when it was translated from UTF-8. That is because the 1510 * value could not have been present as-is in the UTF-8. 1511 * 1512 * To see that CASE_IGNORE is a consistent value, note that it is 1513 * always used for NUL and other uninteresting C0 controls. 1514 */ 1515#if OPT_C1_PRINT 1516 if (!screen->c1_printable) 1517#endif 1518 if (screen->wide_chars 1519 && (c >= 128 && c < 160)) { 1520 sp->nextstate = CASE_IGNORE; 1521 } 1522 1523 /* 1524 * If this character is a different width than the last one, put the 1525 * previous text into the buffer and draw it now. 1526 */ 1527 this_is_wide = isWide((int) c); 1528 if (this_is_wide != sp->last_was_wide) { 1529 WriteNow(); 1530 } 1531#endif 1532 1533 /* 1534 * Accumulate string for printable text. This may be 8/16-bit 1535 * characters. 1536 */ 1537 if (sp->nextstate == CASE_PRINT) { 1538 SafeAlloc(IChar, sp->print_area, sp->print_used, sp->print_size); 1539 if (new_string == 0) { 1540 fprintf(stderr, 1541 "Cannot allocate %lu bytes for printable text\n", 1542 (unsigned long) new_length); 1543 continue; 1544 } 1545#if OPT_VT52_MODE 1546 /* 1547 * Strip output text to 7-bits for VT52. We should do this for 1548 * VT100 also (which is a 7-bit device), but xterm has been 1549 * doing this for so long we shouldn't change this behavior. 1550 */ 1551 if (screen->vtXX_level < 1) 1552 c &= 0x7f; 1553#endif 1554 sp->print_area = new_string; 1555 sp->print_size = new_length; 1556 sp->print_area[sp->print_used++] = (IChar) c; 1557 sp->lastchar = thischar = (int) c; 1558#if OPT_WIDE_CHARS 1559 sp->last_was_wide = this_is_wide; 1560#endif 1561 if (morePtyData(screen, VTbuffer)) { 1562 continue; 1563 } 1564 } 1565 1566 if (sp->nextstate == CASE_PRINT 1567 || (laststate == CASE_PRINT && sp->print_used)) { 1568 WriteNow(); 1569 } 1570 1571 /* 1572 * Accumulate string for APC, DCS, PM, OSC, SOS controls 1573 * This should always be 8-bit characters. 1574 */ 1575 if (sp->parsestate == sos_table) { 1576 SafeAlloc(Char, sp->string_area, sp->string_used, sp->string_size); 1577 if (new_string == 0) { 1578 fprintf(stderr, 1579 "Cannot allocate %lu bytes for string mode %d\n", 1580 (unsigned long) new_length, sp->string_mode); 1581 continue; 1582 } 1583#if OPT_WIDE_CHARS 1584 /* 1585 * We cannot display codes above 255, but let's try to 1586 * accommodate the application a little by not aborting the 1587 * string. 1588 */ 1589 if ((c & 0xffff) > 255) { 1590 sp->nextstate = CASE_PRINT; 1591 c = '?'; 1592 } 1593#endif 1594 sp->string_area = new_string; 1595 sp->string_size = new_length; 1596 sp->string_area[(sp->string_used)++] = CharOf(c); 1597 } else if (sp->parsestate != esc_table) { 1598 /* if we were accumulating, we're not any more */ 1599 sp->string_mode = 0; 1600 sp->string_used = 0; 1601 } 1602 1603 TRACE(("parse %04X -> %d %s\n", c, sp->nextstate, which_table(sp->parsestate))); 1604 1605 switch (sp->nextstate) { 1606 case CASE_PRINT: 1607 TRACE(("CASE_PRINT - printable characters\n")); 1608 break; 1609 1610 case CASE_GROUND_STATE: 1611 TRACE(("CASE_GROUND_STATE - exit ignore mode\n")); 1612 ResetState(sp); 1613 break; 1614 1615 case CASE_IGNORE: 1616 TRACE(("CASE_IGNORE - Ignore character %02X\n", c)); 1617 break; 1618 1619 case CASE_ENQ: 1620 TRACE(("CASE_ENQ - answerback\n")); 1621 for (count = 0; screen->answer_back[count] != 0; count++) 1622 unparseputc(xw, screen->answer_back[count]); 1623 unparse_end(xw); 1624 break; 1625 1626 case CASE_BELL: 1627 TRACE(("CASE_BELL - bell\n")); 1628 if (sp->string_mode == ANSI_OSC) { 1629 if (sp->string_used) 1630 sp->string_area[--(sp->string_used)] = '\0'; 1631 do_osc(xw, sp->string_area, sp->string_used, (int) c); 1632 ResetState(sp); 1633 } else { 1634 /* bell */ 1635 Bell(xw, XkbBI_TerminalBell, 0); 1636 } 1637 break; 1638 1639 case CASE_BS: 1640 TRACE(("CASE_BS - backspace\n")); 1641 CursorBack(xw, 1); 1642 break; 1643 1644 case CASE_CR: 1645 /* CR */ 1646 CarriageReturn(screen); 1647 break; 1648 1649 case CASE_ESC: 1650 if_OPT_VT52_MODE(screen, { 1651 sp->parsestate = vt52_esc_table; 1652 break; 1653 }); 1654 sp->parsestate = esc_table; 1655 break; 1656 1657#if OPT_VT52_MODE 1658 case CASE_VT52_CUP: 1659 TRACE(("CASE_VT52_CUP - VT52 cursor addressing\n")); 1660 sp->vt52_cup = True; 1661 nparam = 0; 1662 break; 1663 1664 case CASE_VT52_IGNORE: 1665 TRACE(("CASE_VT52_IGNORE - VT52 ignore-character\n")); 1666 sp->parsestate = vt52_ignore_table; 1667 break; 1668#endif 1669 1670 case CASE_VMOT: 1671 /* 1672 * form feed, line feed, vertical tab 1673 */ 1674 xtermAutoPrint(xw, c); 1675 xtermIndex(xw, 1); 1676 if (xw->flags & LINEFEED) 1677 CarriageReturn(screen); 1678 else 1679 do_xevents(); 1680 break; 1681 1682 case CASE_CBT: 1683 /* cursor backward tabulation */ 1684 if ((count = param[0]) == DEFAULT) 1685 count = 1; 1686 while ((count-- > 0) 1687 && (TabToPrevStop(xw))) ; 1688 ResetState(sp); 1689 break; 1690 1691 case CASE_CHT: 1692 /* cursor forward tabulation */ 1693 if ((count = param[0]) == DEFAULT) 1694 count = 1; 1695 while ((count-- > 0) 1696 && (TabToNextStop(xw))) ; 1697 ResetState(sp); 1698 break; 1699 1700 case CASE_TAB: 1701 /* tab */ 1702 TabToNextStop(xw); 1703 break; 1704 1705 case CASE_SI: 1706 screen->curgl = 0; 1707 if_OPT_VT52_MODE(screen, { 1708 ResetState(sp); 1709 }); 1710 break; 1711 1712 case CASE_SO: 1713 screen->curgl = 1; 1714 if_OPT_VT52_MODE(screen, { 1715 ResetState(sp); 1716 }); 1717 break; 1718 1719 case CASE_DECDHL: 1720 xterm_DECDHL(xw, c == '3'); 1721 ResetState(sp); 1722 break; 1723 1724 case CASE_DECSWL: 1725 xterm_DECSWL(xw); 1726 ResetState(sp); 1727 break; 1728 1729 case CASE_DECDWL: 1730 xterm_DECDWL(xw); 1731 ResetState(sp); 1732 break; 1733 1734 case CASE_SCR_STATE: 1735 /* enter scr state */ 1736 sp->parsestate = scrtable; 1737 break; 1738 1739 case CASE_SCS0_STATE: 1740 /* enter scs state 0 */ 1741 select_charset(sp, 0, 94); 1742 break; 1743 1744 case CASE_SCS1_STATE: 1745 /* enter scs state 1 */ 1746 select_charset(sp, 1, 94); 1747 break; 1748 1749 case CASE_SCS2_STATE: 1750 /* enter scs state 2 */ 1751 select_charset(sp, 2, 94); 1752 break; 1753 1754 case CASE_SCS3_STATE: 1755 /* enter scs state 3 */ 1756 select_charset(sp, 3, 94); 1757 break; 1758 1759 case CASE_SCS1A_STATE: 1760 /* enter scs state 1 */ 1761 select_charset(sp, 1, 96); 1762 break; 1763 1764 case CASE_SCS2A_STATE: 1765 /* enter scs state 2 */ 1766 select_charset(sp, 2, 96); 1767 break; 1768 1769 case CASE_SCS3A_STATE: 1770 /* enter scs state 3 */ 1771 select_charset(sp, 3, 96); 1772 break; 1773 1774 case CASE_ESC_IGNORE: 1775 /* unknown escape sequence */ 1776 sp->parsestate = eigtable; 1777 break; 1778 1779 case CASE_ESC_DIGIT: 1780 /* digit in csi or dec mode */ 1781 if (nparam > 0) { 1782 if ((row = param[nparam - 1]) == DEFAULT) 1783 row = 0; 1784 param[nparam - 1] = (10 * row) + ((int) c - '0'); 1785 if (param[nparam - 1] > 65535) 1786 param[nparam - 1] = 65535; 1787 if (sp->parsestate == csi_table) 1788 sp->parsestate = csi2_table; 1789 } 1790 break; 1791 1792 case CASE_ESC_SEMI: 1793 /* semicolon in csi or dec mode */ 1794 if (nparam < NPARAM) 1795 param[nparam++] = DEFAULT; 1796 if (sp->parsestate == csi_table) 1797 sp->parsestate = csi2_table; 1798 break; 1799 1800 case CASE_DEC_STATE: 1801 /* enter dec mode */ 1802 sp->parsestate = dec_table; 1803 break; 1804 1805 case CASE_DEC2_STATE: 1806 /* enter dec2 mode */ 1807 sp->parsestate = dec2_table; 1808 break; 1809 1810 case CASE_DEC3_STATE: 1811 /* enter dec3 mode */ 1812 sp->parsestate = dec3_table; 1813 break; 1814 1815 case CASE_ICH: 1816 TRACE(("CASE_ICH - insert char\n")); 1817 if ((row = param[0]) < 1) 1818 row = 1; 1819 InsertChar(xw, (unsigned) row); 1820 ResetState(sp); 1821 break; 1822 1823 case CASE_CUU: 1824 TRACE(("CASE_CUU - cursor up\n")); 1825 if ((row = param[0]) < 1) 1826 row = 1; 1827 CursorUp(screen, row); 1828 ResetState(sp); 1829 break; 1830 1831 case CASE_CUD: 1832 TRACE(("CASE_CUD - cursor down\n")); 1833 if ((row = param[0]) < 1) 1834 row = 1; 1835 CursorDown(screen, row); 1836 ResetState(sp); 1837 break; 1838 1839 case CASE_CUF: 1840 TRACE(("CASE_CUF - cursor forward\n")); 1841 if ((col = param[0]) < 1) 1842 col = 1; 1843 CursorForward(screen, col); 1844 ResetState(sp); 1845 break; 1846 1847 case CASE_CUB: 1848 TRACE(("CASE_CUB - cursor backward\n")); 1849 if ((col = param[0]) < 1) 1850 col = 1; 1851 CursorBack(xw, col); 1852 ResetState(sp); 1853 break; 1854 1855 case CASE_CUP: 1856 TRACE(("CASE_CUP - cursor position\n")); 1857 if_OPT_XMC_GLITCH(screen, { 1858 Jump_XMC(xw); 1859 }); 1860 if ((row = param[0]) < 1) 1861 row = 1; 1862 if (nparam < 2 || (col = param[1]) < 1) 1863 col = 1; 1864 CursorSet(screen, row - 1, col - 1, xw->flags); 1865 ResetState(sp); 1866 break; 1867 1868 case CASE_VPA: 1869 TRACE(("CASE_VPA - vertical position\n")); 1870 if ((row = param[0]) < 1) 1871 row = 1; 1872 CursorSet(screen, row - 1, screen->cur_col, xw->flags); 1873 ResetState(sp); 1874 break; 1875 1876 case CASE_HPA: 1877 TRACE(("CASE_HPA - horizontal position\n")); 1878 if ((col = param[0]) < 1) 1879 col = 1; 1880 CursorSet(screen, screen->cur_row, col - 1, xw->flags); 1881 ResetState(sp); 1882 break; 1883 1884 case CASE_HP_BUGGY_LL: 1885 TRACE(("CASE_HP_BUGGY_LL\n")); 1886 /* Some HP-UX applications have the bug that they 1887 assume ESC F goes to the lower left corner of 1888 the screen, regardless of what terminfo says. */ 1889 if (screen->hp_ll_bc) 1890 CursorSet(screen, screen->max_row, 0, xw->flags); 1891 ResetState(sp); 1892 break; 1893 1894 case CASE_ED: 1895 TRACE(("CASE_ED - erase display\n")); 1896 do_erase_display(xw, param[0], OFF_PROTECT); 1897 ResetState(sp); 1898 break; 1899 1900 case CASE_EL: 1901 TRACE(("CASE_EL - erase line\n")); 1902 do_erase_line(xw, param[0], OFF_PROTECT); 1903 ResetState(sp); 1904 break; 1905 1906 case CASE_ECH: 1907 TRACE(("CASE_ECH - erase char\n")); 1908 /* ECH */ 1909 ClearRight(xw, param[0] < 1 ? 1 : param[0]); 1910 ResetState(sp); 1911 break; 1912 1913 case CASE_IL: 1914 TRACE(("CASE_IL - insert line\n")); 1915 if ((row = param[0]) < 1) 1916 row = 1; 1917 InsertLine(xw, row); 1918 ResetState(sp); 1919 break; 1920 1921 case CASE_DL: 1922 TRACE(("CASE_DL - delete line\n")); 1923 if ((row = param[0]) < 1) 1924 row = 1; 1925 DeleteLine(xw, row); 1926 ResetState(sp); 1927 break; 1928 1929 case CASE_DCH: 1930 TRACE(("CASE_DCH - delete char\n")); 1931 if ((row = param[0]) < 1) 1932 row = 1; 1933 DeleteChar(xw, (unsigned) row); 1934 ResetState(sp); 1935 break; 1936 1937 case CASE_TRACK_MOUSE: 1938 /* 1939 * A single parameter other than zero is always scroll-down. 1940 * A zero-parameter is used to reset the mouse mode, and is 1941 * not useful for scrolling anyway. 1942 */ 1943 if (nparam > 1 || param[0] == 0) { 1944 CELL start; 1945 1946 TRACE(("CASE_TRACK_MOUSE\n")); 1947 /* Track mouse as long as in window and between 1948 * specified rows 1949 */ 1950 start.row = one_if_default(2) - 1; 1951 start.col = param[1] - 1; 1952 TrackMouse(xw, 1953 param[0], 1954 &start, 1955 param[3] - 1, param[4] - 2); 1956 } else { 1957 TRACE(("CASE_SD - scroll down\n")); 1958 /* SD */ 1959 if ((count = param[0]) < 1) 1960 count = 1; 1961 RevScroll(xw, count); 1962 do_xevents(); 1963 } 1964 ResetState(sp); 1965 break; 1966 1967 case CASE_DECID: 1968 TRACE(("CASE_DECID\n")); 1969 if_OPT_VT52_MODE(screen, { 1970 unparseputc(xw, ANSI_ESC); 1971 unparseputc(xw, '/'); 1972 unparseputc(xw, 'Z'); 1973 unparse_end(xw); 1974 ResetState(sp); 1975 break; 1976 }); 1977 param[0] = DEFAULT; /* Default ID parameter */ 1978 /* FALLTHRU */ 1979 case CASE_DA1: 1980 TRACE(("CASE_DA1\n")); 1981 if (param[0] <= 0) { /* less than means DEFAULT */ 1982 count = 0; 1983 reply.a_type = ANSI_CSI; 1984 reply.a_pintro = '?'; 1985 1986 /* The first param corresponds to the highest 1987 * operating level (i.e., service level) of the 1988 * emulation. A DEC terminal can be setup to 1989 * respond with a different DA response, but 1990 * there's no control sequence that modifies this. 1991 * We set it via a resource. 1992 */ 1993 if (screen->terminal_id < 200) { 1994 switch (screen->terminal_id) { 1995 case 102: 1996 reply.a_param[count++] = 6; /* VT102 */ 1997 break; 1998 case 101: 1999 reply.a_param[count++] = 1; /* VT101 */ 2000 reply.a_param[count++] = 0; /* no options */ 2001 break; 2002 default: /* VT100 */ 2003 reply.a_param[count++] = 1; /* VT100 */ 2004 reply.a_param[count++] = 2; /* AVO */ 2005 break; 2006 } 2007 } else { 2008 reply.a_param[count++] = (ParmType) (60 2009 + screen->terminal_id 2010 / 100); 2011 reply.a_param[count++] = 1; /* 132-columns */ 2012 reply.a_param[count++] = 2; /* printer */ 2013 reply.a_param[count++] = 6; /* selective-erase */ 2014#if OPT_SUNPC_KBD 2015 if (xw->keyboard.type == keyboardIsVT220) 2016#endif 2017 reply.a_param[count++] = 8; /* user-defined-keys */ 2018 reply.a_param[count++] = 9; /* national replacement charsets */ 2019 reply.a_param[count++] = 15; /* technical characters */ 2020 if_OPT_ISO_COLORS(screen, { 2021 reply.a_param[count++] = 22; /* ANSI color, VT525 */ 2022 }); 2023#if OPT_DEC_LOCATOR 2024 reply.a_param[count++] = 29; /* ANSI text locator */ 2025#endif 2026 } 2027 reply.a_nparam = (ParmType) count; 2028 reply.a_inters = 0; 2029 reply.a_final = 'c'; 2030 unparseseq(xw, &reply); 2031 } 2032 ResetState(sp); 2033 break; 2034 2035 case CASE_DA2: 2036 TRACE(("CASE_DA2\n")); 2037 if (param[0] <= 0) { /* less than means DEFAULT */ 2038 count = 0; 2039 reply.a_type = ANSI_CSI; 2040 reply.a_pintro = '>'; 2041 2042 if (screen->terminal_id >= 200) 2043 reply.a_param[count++] = 1; /* VT220 */ 2044 else 2045 reply.a_param[count++] = 0; /* VT100 (nonstandard) */ 2046 reply.a_param[count++] = XTERM_PATCH; /* Version */ 2047 reply.a_param[count++] = 0; /* options (none) */ 2048 reply.a_nparam = (ParmType) count; 2049 reply.a_inters = 0; 2050 reply.a_final = 'c'; 2051 unparseseq(xw, &reply); 2052 } 2053 ResetState(sp); 2054 break; 2055 2056 case CASE_DECRPTUI: 2057 TRACE(("CASE_DECRPTUI\n")); 2058 if ((screen->terminal_id >= 400) 2059 && (param[0] <= 0)) { /* less than means DEFAULT */ 2060 unparseputc1(xw, ANSI_DCS); 2061 unparseputc(xw, '!'); 2062 unparseputc(xw, '|'); 2063 unparseputc(xw, '0'); 2064 unparseputc1(xw, ANSI_ST); 2065 unparse_end(xw); 2066 } 2067 ResetState(sp); 2068 break; 2069 2070 case CASE_TBC: 2071 TRACE(("CASE_TBC - tab clear\n")); 2072 if ((row = param[0]) <= 0) /* less than means default */ 2073 TabClear(xw->tabs, screen->cur_col); 2074 else if (row == 3) 2075 TabZonk(xw->tabs); 2076 ResetState(sp); 2077 break; 2078 2079 case CASE_SET: 2080 TRACE(("CASE_SET - set mode\n")); 2081 ansi_modes(xw, bitset); 2082 ResetState(sp); 2083 break; 2084 2085 case CASE_RST: 2086 TRACE(("CASE_RST - reset mode\n")); 2087 ansi_modes(xw, bitclr); 2088 ResetState(sp); 2089 break; 2090 2091 case CASE_SGR: 2092 for (row = 0; row < nparam; ++row) { 2093 if_OPT_XMC_GLITCH(screen, { 2094 Mark_XMC(xw, param[row]); 2095 }); 2096 TRACE(("CASE_SGR %d\n", param[row])); 2097 switch (param[row]) { 2098 case DEFAULT: 2099 case 0: 2100 UIntClr(xw->flags, 2101 (INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE)); 2102 if_OPT_ISO_COLORS(screen, { 2103 reset_SGR_Colors(xw); 2104 }); 2105 break; 2106 case 1: /* Bold */ 2107 xw->flags |= BOLD; 2108 if_OPT_ISO_COLORS(screen, { 2109 setExtendedFG(xw); 2110 }); 2111 break; 2112 case 5: /* Blink */ 2113 xw->flags |= BLINK; 2114 StartBlinking(screen); 2115 if_OPT_ISO_COLORS(screen, { 2116 setExtendedFG(xw); 2117 }); 2118 break; 2119 case 4: /* Underscore */ 2120 xw->flags |= UNDERLINE; 2121 if_OPT_ISO_COLORS(screen, { 2122 setExtendedFG(xw); 2123 }); 2124 break; 2125 case 7: 2126 xw->flags |= INVERSE; 2127 if_OPT_ISO_COLORS(screen, { 2128 setExtendedBG(xw); 2129 }); 2130 break; 2131 case 8: 2132 xw->flags |= INVISIBLE; 2133 break; 2134 case 22: /* reset 'bold' */ 2135 UIntClr(xw->flags, BOLD); 2136 if_OPT_ISO_COLORS(screen, { 2137 setExtendedFG(xw); 2138 }); 2139 break; 2140 case 24: 2141 UIntClr(xw->flags, UNDERLINE); 2142 if_OPT_ISO_COLORS(screen, { 2143 setExtendedFG(xw); 2144 }); 2145 break; 2146 case 25: /* reset 'blink' */ 2147 UIntClr(xw->flags, BLINK); 2148 if_OPT_ISO_COLORS(screen, { 2149 setExtendedFG(xw); 2150 }); 2151 break; 2152 case 27: 2153 UIntClr(xw->flags, INVERSE); 2154 if_OPT_ISO_COLORS(screen, { 2155 setExtendedBG(xw); 2156 }); 2157 break; 2158 case 28: 2159 UIntClr(xw->flags, INVISIBLE); 2160 break; 2161 case 30: 2162 case 31: 2163 case 32: 2164 case 33: 2165 case 34: 2166 case 35: 2167 case 36: 2168 case 37: 2169 if_OPT_ISO_COLORS(screen, { 2170 xw->sgr_foreground = (param[row] - 30); 2171 xw->sgr_extended = False; 2172 setExtendedFG(xw); 2173 }); 2174 break; 2175 case 38: 2176 /* This is more complicated than I'd 2177 like, but it should properly eat all 2178 the parameters for unsupported modes 2179 */ 2180 if_OPT_ISO_COLORS(screen, { 2181 row++; 2182 if (row < nparam) { 2183 switch (param[row]) { 2184 case 5: 2185 row++; 2186 if (row < nparam && 2187 param[row] < NUM_ANSI_COLORS) { 2188 xw->sgr_foreground = param[row]; 2189 xw->sgr_extended = True; 2190 setExtendedFG(xw); 2191 } 2192 break; 2193 default: 2194 row += 7; 2195 break; 2196 } 2197 } 2198 }); 2199 break; 2200 case 39: 2201 if_OPT_ISO_COLORS(screen, { 2202 reset_SGR_Foreground(xw); 2203 }); 2204 break; 2205 case 40: 2206 case 41: 2207 case 42: 2208 case 43: 2209 case 44: 2210 case 45: 2211 case 46: 2212 case 47: 2213 if_OPT_ISO_COLORS(screen, { 2214 xw->sgr_background = (param[row] - 40); 2215 setExtendedBG(xw); 2216 }); 2217 break; 2218 case 48: 2219 if_OPT_ISO_COLORS(screen, { 2220 row++; 2221 if (row < nparam) { 2222 switch (param[row]) { 2223 case 5: 2224 row++; 2225 if (row < nparam && 2226 param[row] < NUM_ANSI_COLORS) { 2227 xw->sgr_background = param[row]; 2228 setExtendedBG(xw); 2229 } 2230 break; 2231 default: 2232 row += 7; 2233 break; 2234 } 2235 } 2236 }); 2237 break; 2238 case 49: 2239 if_OPT_ISO_COLORS(screen, { 2240 reset_SGR_Background(xw); 2241 }); 2242 break; 2243 case 90: 2244 case 91: 2245 case 92: 2246 case 93: 2247 case 94: 2248 case 95: 2249 case 96: 2250 case 97: 2251 if_OPT_AIX_COLORS(screen, { 2252 xw->sgr_foreground = (param[row] - 90 + 8); 2253 xw->sgr_extended = False; 2254 setExtendedFG(xw); 2255 }); 2256 break; 2257 case 100: 2258#if !OPT_AIX_COLORS 2259 if_OPT_ISO_COLORS(screen, { 2260 reset_SGR_Foreground(xw); 2261 reset_SGR_Background(xw); 2262 }); 2263 break; 2264#endif 2265 case 101: 2266 case 102: 2267 case 103: 2268 case 104: 2269 case 105: 2270 case 106: 2271 case 107: 2272 if_OPT_AIX_COLORS(screen, { 2273 xw->sgr_background = (param[row] - 100 + 8); 2274 setExtendedBG(xw); 2275 }); 2276 break; 2277 } 2278 } 2279 ResetState(sp); 2280 break; 2281 2282 /* DSR (except for the '?') is a superset of CPR */ 2283 case CASE_DSR: 2284 sp->private_function = True; 2285 2286 /* FALLTHRU */ 2287 case CASE_CPR: 2288 TRACE(("CASE_CPR - cursor position\n")); 2289 count = 0; 2290 reply.a_type = ANSI_CSI; 2291 reply.a_pintro = CharOf(sp->private_function ? '?' : 0); 2292 reply.a_inters = 0; 2293 reply.a_final = 'n'; 2294 2295 switch (param[0]) { 2296 case 5: 2297 /* operating status */ 2298 reply.a_param[count++] = 0; /* (no malfunction ;-) */ 2299 break; 2300 case 6: 2301 /* CPR */ 2302 /* DECXCPR (with page=0) */ 2303 reply.a_param[count++] = (ParmType) (screen->cur_row + 1); 2304 reply.a_param[count++] = (ParmType) (screen->cur_col + 1); 2305 reply.a_final = 'R'; 2306 break; 2307 case 15: 2308 /* printer status */ 2309 if (screen->terminal_id >= 200) { /* VT220 */ 2310 reply.a_param[count++] = 13; /* implement printer */ 2311 } 2312 break; 2313 case 25: 2314 /* UDK status */ 2315 if (screen->terminal_id >= 200) { /* VT220 */ 2316 reply.a_param[count++] = 20; /* UDK always unlocked */ 2317 } 2318 break; 2319 case 26: 2320 /* keyboard status */ 2321 if (screen->terminal_id >= 200) { /* VT220 */ 2322 reply.a_param[count++] = 27; 2323 reply.a_param[count++] = 1; /* North American */ 2324 if (screen->terminal_id >= 400) { 2325 reply.a_param[count++] = 0; /* ready */ 2326 reply.a_param[count++] = 0; /* LK201 */ 2327 } 2328 } 2329 break; 2330 case 53: 2331 /* Locator status */ 2332 if (screen->terminal_id >= 200) { /* VT220 */ 2333#if OPT_DEC_LOCATOR 2334 reply.a_param[count++] = 50; /* locator ready */ 2335#else 2336 reply.a_param[count++] = 53; /* no locator */ 2337#endif 2338 } 2339 break; 2340 default: 2341 break; 2342 } 2343 2344 if ((reply.a_nparam = (ParmType) count) != 0) 2345 unparseseq(xw, &reply); 2346 2347 ResetState(sp); 2348 sp->private_function = False; 2349 break; 2350 2351 case CASE_MC: 2352 TRACE(("CASE_MC - media control\n")); 2353 xtermMediaControl(xw, param[0], False); 2354 ResetState(sp); 2355 break; 2356 2357 case CASE_DEC_MC: 2358 TRACE(("CASE_DEC_MC - DEC media control\n")); 2359 xtermMediaControl(xw, param[0], True); 2360 ResetState(sp); 2361 break; 2362 2363 case CASE_HP_MEM_LOCK: 2364 case CASE_HP_MEM_UNLOCK: 2365 TRACE(("%s\n", ((sp->parsestate[c] == CASE_HP_MEM_LOCK) 2366 ? "CASE_HP_MEM_LOCK" 2367 : "CASE_HP_MEM_UNLOCK"))); 2368 if (screen->scroll_amt) 2369 FlushScroll(xw); 2370 if (sp->parsestate[c] == CASE_HP_MEM_LOCK) 2371 set_tb_margins(screen, screen->cur_row, screen->bot_marg); 2372 else 2373 set_tb_margins(screen, 0, screen->bot_marg); 2374 ResetState(sp); 2375 break; 2376 2377 case CASE_DECSTBM: 2378 TRACE(("CASE_DECSTBM - set scrolling region\n")); 2379 if ((top = param[0]) < 1) 2380 top = 1; 2381 if (nparam < 2 || (bot = param[1]) == DEFAULT 2382 || bot > MaxRows(screen) 2383 || bot == 0) 2384 bot = MaxRows(screen); 2385 if (bot > top) { 2386 if (screen->scroll_amt) 2387 FlushScroll(xw); 2388 set_tb_margins(screen, top - 1, bot - 1); 2389 CursorSet(screen, 0, 0, xw->flags); 2390 } 2391 ResetState(sp); 2392 break; 2393 2394 case CASE_DECREQTPARM: 2395 TRACE(("CASE_DECREQTPARM\n")); 2396 if (screen->terminal_id < 200) { /* VT102 */ 2397 if ((row = param[0]) == DEFAULT) 2398 row = 0; 2399 if (row == 0 || row == 1) { 2400 reply.a_type = ANSI_CSI; 2401 reply.a_pintro = 0; 2402 reply.a_nparam = 7; 2403 reply.a_param[0] = (ParmType) (row + 2); 2404 reply.a_param[1] = 1; /* no parity */ 2405 reply.a_param[2] = 1; /* eight bits */ 2406 reply.a_param[3] = 128; /* transmit 38.4k baud */ 2407 reply.a_param[4] = 128; /* receive 38.4k baud */ 2408 reply.a_param[5] = 1; /* clock multiplier ? */ 2409 reply.a_param[6] = 0; /* STP flags ? */ 2410 reply.a_inters = 0; 2411 reply.a_final = 'x'; 2412 unparseseq(xw, &reply); 2413 } 2414 } 2415 ResetState(sp); 2416 break; 2417 2418 case CASE_DECSET: 2419 /* DECSET */ 2420#if OPT_VT52_MODE 2421 if (screen->vtXX_level != 0) 2422#endif 2423 dpmodes(xw, bitset); 2424 ResetState(sp); 2425#if OPT_TEK4014 2426 if (TEK4014_ACTIVE(xw)) 2427 return False; 2428#endif 2429 break; 2430 2431 case CASE_DECRST: 2432 /* DECRST */ 2433 dpmodes(xw, bitclr); 2434 init_groundtable(screen, sp); 2435 ResetState(sp); 2436 break; 2437 2438 case CASE_DECALN: 2439 TRACE(("CASE_DECALN - alignment test\n")); 2440 if (screen->cursor_state) 2441 HideCursor(); 2442 set_tb_margins(screen, 0, screen->max_row); 2443 CursorSet(screen, 0, 0, xw->flags); 2444 xtermParseRect(xw, 0, 0, &myRect); 2445 ScrnFillRectangle(xw, &myRect, 'E', 0, False); 2446 ResetState(sp); 2447 break; 2448 2449 case CASE_GSETS: 2450 TRACE(("CASE_GSETS(%d) = '%c'\n", sp->scstype, c)); 2451 if (screen->vtXX_level != 0) 2452 screen->gsets[sp->scstype] = CharOf(c); 2453 ResetState(sp); 2454 break; 2455 2456 case CASE_DECSC: 2457 TRACE(("CASE_DECSC - save cursor\n")); 2458 CursorSave(xw); 2459 ResetState(sp); 2460 break; 2461 2462 case CASE_DECRC: 2463 TRACE(("CASE_DECRC - restore cursor\n")); 2464 CursorRestore(xw); 2465 if_OPT_ISO_COLORS(screen, { 2466 setExtendedFG(xw); 2467 }); 2468 ResetState(sp); 2469 break; 2470 2471 case CASE_DECKPAM: 2472 TRACE(("CASE_DECKPAM\n")); 2473 xw->keyboard.flags |= MODE_DECKPAM; 2474 update_appkeypad(); 2475 ResetState(sp); 2476 break; 2477 2478 case CASE_DECKPNM: 2479 TRACE(("CASE_DECKPNM\n")); 2480 UIntClr(xw->keyboard.flags, MODE_DECKPAM); 2481 update_appkeypad(); 2482 ResetState(sp); 2483 break; 2484 2485 case CASE_CSI_QUOTE_STATE: 2486 sp->parsestate = csi_quo_table; 2487 break; 2488 2489#if OPT_BLINK_CURS 2490 case CASE_CSI_SPACE_STATE: 2491 sp->parsestate = csi_sp_table; 2492 break; 2493 2494 case CASE_DECSCUSR: 2495 TRACE(("CASE_DECSCUSR\n")); 2496 { 2497 Boolean change = True; 2498 Boolean blinks = screen->cursor_blink; 2499 2500 HideCursor(); 2501 2502 switch (param[0]) { 2503 case 0: 2504 case 1: 2505 case DEFAULT: 2506 /* blinking block */ 2507 screen->cursor_underline = False; 2508 blinks = True; 2509 break; 2510 case 2: 2511 /* steady block */ 2512 screen->cursor_underline = False; 2513 blinks = False; 2514 break; 2515 case 3: 2516 /* blinking underline */ 2517 screen->cursor_underline = True; 2518 blinks = True; 2519 break; 2520 case 4: 2521 /* steady underline */ 2522 screen->cursor_underline = True; 2523 blinks = False; 2524 break; 2525 default: 2526 change = False; 2527 break; 2528 } 2529 2530 if (change) { 2531 xtermSetCursorBox(screen); 2532 SetCursorBlink(screen, blinks); 2533 } 2534 } 2535 ResetState(sp); 2536 break; 2537#endif 2538 2539#if OPT_SCROLL_LOCK 2540 case CASE_DECLL: 2541 TRACE(("CASE_DECLL\n")); 2542 if (nparam > 0) { 2543 for (count = 0; count < nparam; ++count) { 2544 switch (param[count]) { 2545 case 0: 2546 case DEFAULT: 2547 xtermClearLEDs(screen); 2548 break; 2549 case 1: 2550 case 2: 2551 case 3: 2552 xtermShowLED(screen, (Cardinal) param[count], True); 2553 break; 2554 case 21: 2555 case 22: 2556 case 23: 2557 xtermShowLED(screen, (Cardinal) (param[count] - 20), True); 2558 break; 2559 } 2560 } 2561 } else { 2562 xtermClearLEDs(screen); 2563 } 2564 ResetState(sp); 2565 break; 2566#endif 2567 2568#if OPT_VT52_MODE 2569 case CASE_VT52_FINISH: 2570 TRACE(("CASE_VT52_FINISH terminal_id %d, vtXX_level %d\n", 2571 screen->terminal_id, 2572 screen->vtXX_level)); 2573 if (screen->terminal_id >= 100 2574 && screen->vtXX_level == 0) { 2575 sp->groundtable = 2576 sp->parsestate = ansi_table; 2577 screen->vtXX_level = screen->vt52_save_level; 2578 screen->curgl = screen->vt52_save_curgl; 2579 screen->curgr = screen->vt52_save_curgr; 2580 screen->curss = screen->vt52_save_curss; 2581 memmove(screen->gsets, screen->vt52_save_gsets, sizeof(screen->gsets)); 2582 } 2583 break; 2584#endif 2585 2586 case CASE_ANSI_LEVEL_1: 2587 TRACE(("CASE_ANSI_LEVEL_1\n")); 2588 set_ansi_conformance(screen, 1); 2589 ResetState(sp); 2590 break; 2591 2592 case CASE_ANSI_LEVEL_2: 2593 TRACE(("CASE_ANSI_LEVEL_2\n")); 2594 set_ansi_conformance(screen, 2); 2595 ResetState(sp); 2596 break; 2597 2598 case CASE_ANSI_LEVEL_3: 2599 TRACE(("CASE_ANSI_LEVEL_3\n")); 2600 set_ansi_conformance(screen, 3); 2601 ResetState(sp); 2602 break; 2603 2604 case CASE_DECSCL: 2605 TRACE(("CASE_DECSCL(%d,%d)\n", param[0], param[1])); 2606 if (param[0] >= 61 && param[0] <= 65) { 2607 /* 2608 * VT300, VT420, VT520 manuals claim that DECSCL does a hard 2609 * reset (RIS). VT220 manual states that it is a soft reset. 2610 * Perhaps both are right (unlikely). Kermit says it's soft. 2611 */ 2612 VTReset(xw, False, False); 2613 screen->vtXX_level = param[0] - 60; 2614 if (param[0] > 61) { 2615 switch (zero_if_default(1)) { 2616 case 1: 2617 show_8bit_control(False); 2618 break; 2619 case 0: 2620 case 2: 2621 show_8bit_control(True); 2622 break; 2623 } 2624 } 2625 } 2626 ResetState(sp); 2627 break; 2628 2629 case CASE_DECSCA: 2630 TRACE(("CASE_DECSCA\n")); 2631 screen->protected_mode = DEC_PROTECT; 2632 if (param[0] <= 0 || param[0] == 2) 2633 UIntClr(xw->flags, PROTECTED); 2634 else if (param[0] == 1) 2635 xw->flags |= PROTECTED; 2636 ResetState(sp); 2637 break; 2638 2639 case CASE_DECSED: 2640 TRACE(("CASE_DECSED\n")); 2641 do_erase_display(xw, param[0], DEC_PROTECT); 2642 ResetState(sp); 2643 break; 2644 2645 case CASE_DECSEL: 2646 TRACE(("CASE_DECSEL\n")); 2647 do_erase_line(xw, param[0], DEC_PROTECT); 2648 ResetState(sp); 2649 break; 2650 2651 case CASE_ST: 2652 TRACE(("CASE_ST: End of String (%lu bytes)\n", (unsigned long) sp->string_used)); 2653 ResetState(sp); 2654 if (!sp->string_used) 2655 break; 2656 sp->string_area[--(sp->string_used)] = '\0'; 2657 switch (sp->string_mode) { 2658 case ANSI_APC: 2659 /* ignored */ 2660 break; 2661 case ANSI_DCS: 2662 do_dcs(xw, sp->string_area, sp->string_used); 2663 break; 2664 case ANSI_OSC: 2665 do_osc(xw, sp->string_area, sp->string_used, ANSI_ST); 2666 break; 2667 case ANSI_PM: 2668 /* ignored */ 2669 break; 2670 case ANSI_SOS: 2671 /* ignored */ 2672 break; 2673 } 2674 break; 2675 2676 case CASE_SOS: 2677 TRACE(("CASE_SOS: Start of String\n")); 2678 if (ParseSOS(screen)) { 2679 sp->string_mode = ANSI_SOS; 2680 sp->parsestate = sos_table; 2681 } else { 2682 illegal_parse(xw, c, sp); 2683 } 2684 break; 2685 2686 case CASE_PM: 2687 TRACE(("CASE_PM: Privacy Message\n")); 2688 if (ParseSOS(screen)) { 2689 sp->string_mode = ANSI_PM; 2690 sp->parsestate = sos_table; 2691 } else { 2692 illegal_parse(xw, c, sp); 2693 } 2694 break; 2695 2696 case CASE_DCS: 2697 TRACE(("CASE_DCS: Device Control String\n")); 2698 sp->string_mode = ANSI_DCS; 2699 sp->parsestate = sos_table; 2700 break; 2701 2702 case CASE_APC: 2703 TRACE(("CASE_APC: Application Program Command\n")); 2704 if (ParseSOS(screen)) { 2705 sp->string_mode = ANSI_APC; 2706 sp->parsestate = sos_table; 2707 } else { 2708 illegal_parse(xw, c, sp); 2709 } 2710 break; 2711 2712 case CASE_SPA: 2713 TRACE(("CASE_SPA - start protected area\n")); 2714 screen->protected_mode = ISO_PROTECT; 2715 xw->flags |= PROTECTED; 2716 ResetState(sp); 2717 break; 2718 2719 case CASE_EPA: 2720 TRACE(("CASE_EPA - end protected area\n")); 2721 UIntClr(xw->flags, PROTECTED); 2722 ResetState(sp); 2723 break; 2724 2725 case CASE_SU: 2726 TRACE(("CASE_SU - scroll up\n")); 2727 if ((count = param[0]) < 1) 2728 count = 1; 2729 xtermScroll(xw, count); 2730 ResetState(sp); 2731 break; 2732 2733 case CASE_IND: 2734 TRACE(("CASE_IND - index\n")); 2735 xtermIndex(xw, 1); 2736 do_xevents(); 2737 ResetState(sp); 2738 break; 2739 2740 case CASE_CPL: 2741 TRACE(("CASE_CPL - cursor prev line\n")); 2742 CursorPrevLine(screen, param[0]); 2743 ResetState(sp); 2744 break; 2745 2746 case CASE_CNL: 2747 TRACE(("CASE_CNL - cursor next line\n")); 2748 CursorNextLine(screen, param[0]); 2749 ResetState(sp); 2750 break; 2751 2752 case CASE_NEL: 2753 TRACE(("CASE_NEL\n")); 2754 xtermIndex(xw, 1); 2755 CarriageReturn(screen); 2756 ResetState(sp); 2757 break; 2758 2759 case CASE_HTS: 2760 TRACE(("CASE_HTS - horizontal tab set\n")); 2761 TabSet(xw->tabs, screen->cur_col); 2762 ResetState(sp); 2763 break; 2764 2765 case CASE_RI: 2766 TRACE(("CASE_RI - reverse index\n")); 2767 RevIndex(xw, 1); 2768 ResetState(sp); 2769 break; 2770 2771 case CASE_SS2: 2772 TRACE(("CASE_SS2\n")); 2773 screen->curss = 2; 2774 ResetState(sp); 2775 break; 2776 2777 case CASE_SS3: 2778 TRACE(("CASE_SS3\n")); 2779 screen->curss = 3; 2780 ResetState(sp); 2781 break; 2782 2783 case CASE_CSI_STATE: 2784 /* enter csi state */ 2785 nparam = 1; 2786 param[0] = DEFAULT; 2787 sp->parsestate = csi_table; 2788 break; 2789 2790 case CASE_ESC_SP_STATE: 2791 /* esc space */ 2792 sp->parsestate = esc_sp_table; 2793 break; 2794 2795 case CASE_CSI_EX_STATE: 2796 /* csi exclamation */ 2797 sp->parsestate = csi_ex_table; 2798 break; 2799 2800#if OPT_DEC_LOCATOR 2801 case CASE_CSI_TICK_STATE: 2802 /* csi tick (') */ 2803 sp->parsestate = csi_tick_table; 2804 break; 2805 2806 case CASE_DECEFR: 2807 TRACE(("CASE_DECEFR - Enable Filter Rectangle\n")); 2808 if (screen->send_mouse_pos == DEC_LOCATOR) { 2809 MotionOff(screen, xw); 2810 if ((screen->loc_filter_top = param[0]) < 1) 2811 screen->loc_filter_top = LOC_FILTER_POS; 2812 if (nparam < 2 || (screen->loc_filter_left = param[1]) < 1) 2813 screen->loc_filter_left = LOC_FILTER_POS; 2814 if (nparam < 3 || (screen->loc_filter_bottom = param[2]) < 1) 2815 screen->loc_filter_bottom = LOC_FILTER_POS; 2816 if (nparam < 4 || (screen->loc_filter_right = param[3]) < 1) 2817 screen->loc_filter_right = LOC_FILTER_POS; 2818 InitLocatorFilter(xw); 2819 } 2820 ResetState(sp); 2821 break; 2822 2823 case CASE_DECELR: 2824 MotionOff(screen, xw); 2825 if (param[0] <= 0 || param[0] > 2) { 2826 screen->send_mouse_pos = MOUSE_OFF; 2827 TRACE(("DECELR - Disable Locator Reports\n")); 2828 } else { 2829 TRACE(("DECELR - Enable Locator Reports\n")); 2830 screen->send_mouse_pos = DEC_LOCATOR; 2831 xtermShowPointer(xw, True); 2832 if (param[0] == 2) { 2833 screen->locator_reset = True; 2834 } else { 2835 screen->locator_reset = False; 2836 } 2837 if (nparam < 2 || param[1] != 1) { 2838 screen->locator_pixels = False; 2839 } else { 2840 screen->locator_pixels = True; 2841 } 2842 screen->loc_filter = False; 2843 } 2844 ResetState(sp); 2845 break; 2846 2847 case CASE_DECSLE: 2848 TRACE(("DECSLE - Select Locator Events\n")); 2849 for (count = 0; count < nparam; ++count) { 2850 switch (param[count]) { 2851 case DEFAULT: 2852 case 0: 2853 MotionOff(screen, xw); 2854 screen->loc_filter = False; 2855 screen->locator_events = 0; 2856 break; 2857 case 1: 2858 screen->locator_events |= LOC_BTNS_DN; 2859 break; 2860 case 2: 2861 UIntClr(screen->locator_events, LOC_BTNS_DN); 2862 break; 2863 case 3: 2864 screen->locator_events |= LOC_BTNS_UP; 2865 break; 2866 case 4: 2867 UIntClr(screen->locator_events, LOC_BTNS_UP); 2868 break; 2869 } 2870 } 2871 ResetState(sp); 2872 break; 2873 2874 case CASE_DECRQLP: 2875 TRACE(("DECRQLP - Request Locator Position\n")); 2876 if (param[0] < 2) { 2877 /* Issue DECLRP Locator Position Report */ 2878 GetLocatorPosition(xw); 2879 } 2880 ResetState(sp); 2881 break; 2882#endif /* OPT_DEC_LOCATOR */ 2883 2884#if OPT_DEC_RECTOPS 2885 case CASE_CSI_DOLLAR_STATE: 2886 TRACE(("CASE_CSI_DOLLAR_STATE\n")); 2887 /* csi dollar ($) */ 2888 if (screen->vtXX_level >= 3) 2889 sp->parsestate = csi_dollar_table; 2890 else 2891 sp->parsestate = eigtable; 2892 break; 2893 2894 case CASE_CSI_STAR_STATE: 2895 TRACE(("CASE_CSI_STAR_STATE\n")); 2896 /* csi star (*) */ 2897 if (screen->vtXX_level >= 4) 2898 sp->parsestate = csi_star_table; 2899 else 2900 sp->parsestate = eigtable; 2901 break; 2902 2903 case CASE_DECCRA: 2904 if (screen->vtXX_level >= 4) { 2905 TRACE(("CASE_DECCRA - Copy rectangular area\n")); 2906 xtermParseRect(xw, nparam, param, &myRect); 2907 ScrnCopyRectangle(xw, &myRect, nparam - 5, param + 5); 2908 } 2909 ResetState(sp); 2910 break; 2911 2912 case CASE_DECERA: 2913 if (screen->vtXX_level >= 4) { 2914 TRACE(("CASE_DECERA - Erase rectangular area\n")); 2915 xtermParseRect(xw, nparam, param, &myRect); 2916 ScrnFillRectangle(xw, &myRect, ' ', 0, True); 2917 } 2918 ResetState(sp); 2919 break; 2920 2921 case CASE_DECFRA: 2922 if (screen->vtXX_level >= 4) { 2923 TRACE(("CASE_DECFRA - Fill rectangular area\n")); 2924 if (nparam > 0 2925 && ((param[0] >= 32 && param[0] <= 126) 2926 || (param[0] >= 160 && param[0] <= 255))) { 2927 xtermParseRect(xw, nparam - 1, param + 1, &myRect); 2928 ScrnFillRectangle(xw, &myRect, param[0], xw->flags, True); 2929 } 2930 } 2931 ResetState(sp); 2932 break; 2933 2934 case CASE_DECSERA: 2935 if (screen->vtXX_level >= 4) { 2936 TRACE(("CASE_DECSERA - Selective erase rectangular area\n")); 2937 xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect); 2938 ScrnWipeRectangle(xw, &myRect); 2939 } 2940 ResetState(sp); 2941 break; 2942 2943 case CASE_DECSACE: 2944 TRACE(("CASE_DECSACE - Select attribute change extent\n")); 2945 screen->cur_decsace = param[0]; 2946 ResetState(sp); 2947 break; 2948 2949 case CASE_DECCARA: 2950 if (screen->vtXX_level >= 4) { 2951 TRACE(("CASE_DECCARA - Change attributes in rectangular area\n")); 2952 xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect); 2953 ScrnMarkRectangle(xw, &myRect, False, nparam - 4, param + 4); 2954 } 2955 ResetState(sp); 2956 break; 2957 2958 case CASE_DECRARA: 2959 if (screen->vtXX_level >= 4) { 2960 TRACE(("CASE_DECRARA - Reverse attributes in rectangular area\n")); 2961 xtermParseRect(xw, nparam > 4 ? 4 : nparam, param, &myRect); 2962 ScrnMarkRectangle(xw, &myRect, True, nparam - 4, param + 4); 2963 } 2964 ResetState(sp); 2965 break; 2966 2967 case CASE_RQM: 2968 TRACE(("CASE_RQM\n")); 2969 do_rpm(xw, nparam, param); 2970 ResetState(sp); 2971 break; 2972 2973 case CASE_DECRQM: 2974 TRACE(("CASE_DECRQM\n")); 2975 do_decrpm(xw, nparam, param); 2976 ResetState(sp); 2977 break; 2978 2979 case CASE_CSI_DEC_DOLLAR_STATE: 2980 TRACE(("CASE_CSI_DEC_DOLLAR_STATE\n")); 2981 /* csi ? dollar ($) */ 2982 sp->parsestate = csi_dec_dollar_table; 2983 break; 2984#else 2985 case CASE_CSI_DOLLAR_STATE: 2986 /* csi dollar ($) */ 2987 sp->parsestate = eigtable; 2988 break; 2989 2990 case CASE_CSI_STAR_STATE: 2991 /* csi dollar (*) */ 2992 sp->parsestate = eigtable; 2993 break; 2994 2995 case CASE_CSI_DEC_DOLLAR_STATE: 2996 /* csi ? dollar ($) */ 2997 sp->parsestate = eigtable; 2998 break; 2999#endif /* OPT_DEC_RECTOPS */ 3000 3001 case CASE_S7C1T: 3002 TRACE(("CASE_S7C1T\n")); 3003 show_8bit_control(False); 3004 ResetState(sp); 3005 break; 3006 3007 case CASE_S8C1T: 3008 TRACE(("CASE_S8C1T\n")); 3009#if OPT_VT52_MODE 3010 if (screen->vtXX_level <= 1) 3011 break; 3012#endif 3013 show_8bit_control(True); 3014 ResetState(sp); 3015 break; 3016 3017 case CASE_OSC: 3018 TRACE(("CASE_OSC: Operating System Command\n")); 3019 sp->parsestate = sos_table; 3020 sp->string_mode = ANSI_OSC; 3021 break; 3022 3023 case CASE_RIS: 3024 TRACE(("CASE_RIS\n")); 3025 VTReset(xw, True, True); 3026 ResetState(sp); 3027 break; 3028 3029 case CASE_DECSTR: 3030 TRACE(("CASE_DECSTR\n")); 3031 VTReset(xw, False, False); 3032 ResetState(sp); 3033 break; 3034 3035 case CASE_REP: 3036 TRACE(("CASE_REP\n")); 3037 if (sp->lastchar >= 0 && 3038 sp->lastchar < 256 && 3039 sp->groundtable[E2A(sp->lastchar)] == CASE_PRINT) { 3040 IChar repeated[2]; 3041 count = (param[0] < 1) ? 1 : param[0]; 3042 repeated[0] = (IChar) sp->lastchar; 3043 while (count-- > 0) { 3044 dotext(xw, 3045 screen->gsets[(int) (screen->curgl)], 3046 repeated, 1); 3047 } 3048 } 3049 ResetState(sp); 3050 break; 3051 3052 case CASE_LS2: 3053 TRACE(("CASE_LS2\n")); 3054 screen->curgl = 2; 3055 ResetState(sp); 3056 break; 3057 3058 case CASE_LS3: 3059 TRACE(("CASE_LS3\n")); 3060 screen->curgl = 3; 3061 ResetState(sp); 3062 break; 3063 3064 case CASE_LS3R: 3065 TRACE(("CASE_LS3R\n")); 3066 screen->curgr = 3; 3067 ResetState(sp); 3068 break; 3069 3070 case CASE_LS2R: 3071 TRACE(("CASE_LS2R\n")); 3072 screen->curgr = 2; 3073 ResetState(sp); 3074 break; 3075 3076 case CASE_LS1R: 3077 TRACE(("CASE_LS1R\n")); 3078 screen->curgr = 1; 3079 ResetState(sp); 3080 break; 3081 3082 case CASE_XTERM_SAVE: 3083 savemodes(xw); 3084 ResetState(sp); 3085 break; 3086 3087 case CASE_XTERM_RESTORE: 3088 restoremodes(xw); 3089 ResetState(sp); 3090 break; 3091 3092 case CASE_XTERM_WINOPS: 3093 TRACE(("CASE_XTERM_WINOPS\n")); 3094 window_ops(xw); 3095 ResetState(sp); 3096 break; 3097#if OPT_WIDE_CHARS 3098 case CASE_ESC_PERCENT: 3099 sp->parsestate = esc_pct_table; 3100 break; 3101 3102 case CASE_UTF8: 3103 /* If we did not set UTF-8 mode from resource or the 3104 * command-line, allow it to be enabled/disabled by 3105 * control sequence. 3106 */ 3107 if (screen->wide_chars 3108 && screen->utf8_mode != uAlways) { 3109 if (!screen->wide_chars) { 3110 WriteNow(); 3111 ChangeToWide(xw); 3112 } 3113 switchPtyData(screen, c == 'G'); 3114 TRACE(("UTF8 mode %s\n", 3115 BtoS(screen->utf8_mode))); 3116 } else { 3117 TRACE(("UTF8 mode NOT turned %s (%s)\n", 3118 BtoS(c == 'G'), 3119 (screen->utf8_mode == uAlways) 3120 ? "UTF-8 mode set from command-line" 3121 : "wideChars resource was not set")); 3122 } 3123 ResetState(sp); 3124 break; 3125#endif 3126#if OPT_MOD_FKEYS 3127 case CASE_SET_MOD_FKEYS: 3128 TRACE(("CASE_SET_MOD_FKEYS\n")); 3129 if (nparam >= 1) { 3130 set_mod_fkeys(xw, param[0], nparam > 1 ? param[1] : DEFAULT, True); 3131 } else { 3132 for (row = 1; row <= 5; ++row) 3133 set_mod_fkeys(xw, row, DEFAULT, True); 3134 } 3135 break; 3136 case CASE_SET_MOD_FKEYS0: 3137 TRACE(("CASE_SET_MOD_FKEYS0\n")); 3138 if (nparam >= 1 && param[0] != DEFAULT) { 3139 set_mod_fkeys(xw, param[0], -1, False); 3140 } else { 3141 xw->keyboard.modify_now.function_keys = -1; 3142 } 3143 break; 3144#endif 3145 case CASE_HIDE_POINTER: 3146 TRACE(("CASE_HIDE_POINTER\n")); 3147 if (nparam >= 1 && param[0] != DEFAULT) { 3148 screen->pointer_mode = param[0]; 3149 } else { 3150 screen->pointer_mode = DEF_POINTER_MODE; 3151 } 3152 break; 3153 3154 case CASE_SM_TITLE: 3155 TRACE(("CASE_SM_TITLE\n")); 3156 if (nparam >= 1) { 3157 int n; 3158 for (n = 0; n < nparam; ++n) { 3159 if (param[n] != DEFAULT) 3160 screen->title_modes |= (1 << param[n]); 3161 } 3162 } else { 3163 screen->title_modes = DEF_TITLE_MODES; 3164 } 3165 TRACE(("...title_modes %#x\n", screen->title_modes)); 3166 break; 3167 3168 case CASE_RM_TITLE: 3169 TRACE(("CASE_RM_TITLE\n")); 3170 if (nparam >= 1) { 3171 int n; 3172 for (n = 0; n < nparam; ++n) { 3173 if (param[n] != DEFAULT) 3174 screen->title_modes &= ~(1 << param[n]); 3175 } 3176 } else { 3177 screen->title_modes = DEF_TITLE_MODES; 3178 } 3179 TRACE(("...title_modes %#x\n", screen->title_modes)); 3180 break; 3181 3182 case CASE_CSI_IGNORE: 3183 sp->parsestate = cigtable; 3184 break; 3185 3186 case CASE_DECSWBV: 3187 TRACE(("CASE_DECSWBV\n")); 3188 switch ((nparam >= 1) ? param[0] : DEFAULT) { 3189 case 2: 3190 case 3: 3191 case 4: 3192 screen->warningVolume = bvLow; 3193 break; 3194 case 5: 3195 case 6: 3196 case 7: 3197 case 8: 3198 screen->warningVolume = bvHigh; 3199 break; 3200 default: 3201 screen->warningVolume = bvOff; 3202 break; 3203 } 3204 TRACE(("...warningVolume %d\n", screen->warningVolume)); 3205 ResetState(sp); 3206 break; 3207 3208 case CASE_DECSMBV: 3209 TRACE(("CASE_DECSMBV\n")); 3210 switch ((nparam >= 1) ? param[0] : DEFAULT) { 3211 case 2: 3212 case 3: 3213 case 4: 3214 screen->marginVolume = bvLow; 3215 break; 3216 case 0: 3217 case DEFAULT: 3218 case 5: 3219 case 6: 3220 case 7: 3221 case 8: 3222 screen->marginVolume = bvHigh; 3223 break; 3224 default: 3225 screen->marginVolume = bvOff; 3226 break; 3227 } 3228 TRACE(("...marginVolume %d\n", screen->marginVolume)); 3229 ResetState(sp); 3230 break; 3231 } 3232 if (sp->parsestate == sp->groundtable) 3233 sp->lastchar = thischar; 3234 } while (0); 3235 3236#if OPT_WIDE_CHARS 3237 screen->utf8_inparse = (Boolean) ((screen->utf8_mode != uFalse) 3238 && (sp->parsestate != sos_table)); 3239#endif 3240 3241 return True; 3242} 3243 3244static void 3245VTparse(XtermWidget xw) 3246{ 3247 TScreen *screen; 3248 3249 /* We longjmp back to this point in VTReset() */ 3250 (void) setjmp(vtjmpbuf); 3251 screen = TScreenOf(xw); 3252 memset(&myState, 0, sizeof(myState)); 3253 myState.scssize = 94; /* number of printable/nonspace ASCII */ 3254 myState.lastchar = -1; /* not a legal IChar */ 3255 myState.nextstate = -1; /* not a legal state */ 3256 3257 init_groundtable(screen, &myState); 3258 myState.parsestate = myState.groundtable; 3259 3260 do { 3261 } while (doparsing(xw, doinput(), &myState)); 3262} 3263 3264static Char *v_buffer; /* pointer to physical buffer */ 3265static Char *v_bufstr = NULL; /* beginning of area to write */ 3266static Char *v_bufptr; /* end of area to write */ 3267static Char *v_bufend; /* end of physical buffer */ 3268 3269/* Write data to the pty as typed by the user, pasted with the mouse, 3270 or generated by us in response to a query ESC sequence. */ 3271 3272void 3273v_write(int f, const Char * data, unsigned len) 3274{ 3275 int riten; 3276 3277 TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len))); 3278 if (v_bufstr == NULL && len > 0) { 3279 v_buffer = (Char *) XtMalloc((Cardinal) len); 3280 v_bufstr = v_buffer; 3281 v_bufptr = v_buffer; 3282 v_bufend = v_buffer + len; 3283 } 3284#ifdef DEBUG 3285 if (debug) { 3286 fprintf(stderr, "v_write called with %d bytes (%d left over)", 3287 len, v_bufptr - v_bufstr); 3288 if (len > 1 && len < 10) 3289 fprintf(stderr, " \"%.*s\"", len, (const char *) data); 3290 fprintf(stderr, "\n"); 3291 } 3292#endif 3293 3294#ifdef VMS 3295 if ((1 << f) != pty_mask) { 3296 tt_write((const char *) data, len); 3297 return; 3298 } 3299#else /* VMS */ 3300 if (!FD_ISSET(f, &pty_mask)) { 3301 IGNORE_RC(write(f, (const char *) data, (size_t) len)); 3302 return; 3303 } 3304#endif /* VMS */ 3305 3306 /* 3307 * Append to the block we already have. 3308 * Always doing this simplifies the code, and 3309 * isn't too bad, either. If this is a short 3310 * block, it isn't too expensive, and if this is 3311 * a long block, we won't be able to write it all 3312 * anyway. 3313 */ 3314 3315 if (len > 0) { 3316#if OPT_DABBREV 3317 TScreenOf(term)->dabbrev_working = False; /* break dabbrev sequence */ 3318#endif 3319 if (v_bufend < v_bufptr + len) { /* we've run out of room */ 3320 if (v_bufstr != v_buffer) { 3321 /* there is unused space, move everything down */ 3322 /* possibly overlapping memmove here */ 3323#ifdef DEBUG 3324 if (debug) 3325 fprintf(stderr, "moving data down %d\n", 3326 v_bufstr - v_buffer); 3327#endif 3328 memmove(v_buffer, v_bufstr, (size_t) (v_bufptr - v_bufstr)); 3329 v_bufptr -= v_bufstr - v_buffer; 3330 v_bufstr = v_buffer; 3331 } 3332 if (v_bufend < v_bufptr + len) { 3333 /* still won't fit: get more space */ 3334 /* Don't use XtRealloc because an error is not fatal. */ 3335 unsigned size = (unsigned) (v_bufptr - v_buffer); 3336 v_buffer = TypeRealloc(Char, size + len, v_buffer); 3337 if (v_buffer) { 3338#ifdef DEBUG 3339 if (debug) 3340 fprintf(stderr, "expanded buffer to %d\n", 3341 size + len); 3342#endif 3343 v_bufstr = v_buffer; 3344 v_bufptr = v_buffer + size; 3345 v_bufend = v_bufptr + len; 3346 } else { 3347 /* no memory: ignore entire write request */ 3348 fprintf(stderr, "%s: cannot allocate buffer space\n", 3349 ProgramName); 3350 v_buffer = v_bufstr; /* restore clobbered pointer */ 3351 } 3352 } 3353 } 3354 if (v_bufend >= v_bufptr + len) { 3355 /* new stuff will fit */ 3356 memmove(v_bufptr, data, (size_t) len); 3357 v_bufptr += len; 3358 } 3359 } 3360 3361 /* 3362 * Write out as much of the buffer as we can. 3363 * Be careful not to overflow the pty's input silo. 3364 * We are conservative here and only write 3365 * a small amount at a time. 3366 * 3367 * If we can't push all the data into the pty yet, we expect write 3368 * to return a non-negative number less than the length requested 3369 * (if some data written) or -1 and set errno to EAGAIN, 3370 * EWOULDBLOCK, or EINTR (if no data written). 3371 * 3372 * (Not all systems do this, sigh, so the code is actually 3373 * a little more forgiving.) 3374 */ 3375 3376#define MAX_PTY_WRITE 128 /* 1/2 POSIX minimum MAX_INPUT */ 3377 3378 if (v_bufptr > v_bufstr) { 3379#ifdef VMS 3380 riten = tt_write(v_bufstr, 3381 ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE) 3382 ? v_bufptr - v_bufstr 3383 : VMS_TERM_BUFFER_SIZE)); 3384 if (riten == 0) 3385 return (riten); 3386#else /* VMS */ 3387 riten = (int) write(f, v_bufstr, 3388 (size_t) ((v_bufptr - v_bufstr <= MAX_PTY_WRITE) 3389 ? v_bufptr - v_bufstr 3390 : MAX_PTY_WRITE)); 3391 if (riten < 0) 3392#endif /* VMS */ 3393 { 3394#ifdef DEBUG 3395 if (debug) 3396 perror("write"); 3397#endif 3398 riten = 0; 3399 } 3400#ifdef DEBUG 3401 if (debug) 3402 fprintf(stderr, "write called with %d, wrote %d\n", 3403 v_bufptr - v_bufstr <= MAX_PTY_WRITE ? 3404 v_bufptr - v_bufstr : MAX_PTY_WRITE, 3405 riten); 3406#endif 3407 v_bufstr += riten; 3408 if (v_bufstr >= v_bufptr) /* we wrote it all */ 3409 v_bufstr = v_bufptr = v_buffer; 3410 } 3411 3412 /* 3413 * If we have lots of unused memory allocated, return it 3414 */ 3415 if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */ 3416 /* save pointers across realloc */ 3417 int start = (int) (v_bufstr - v_buffer); 3418 int size = (int) (v_bufptr - v_buffer); 3419 unsigned allocsize = (unsigned) (size ? size : 1); 3420 3421 v_buffer = TypeRealloc(Char, allocsize, v_buffer); 3422 if (v_buffer) { 3423 v_bufstr = v_buffer + start; 3424 v_bufptr = v_buffer + size; 3425 v_bufend = v_buffer + allocsize; 3426#ifdef DEBUG 3427 if (debug) 3428 fprintf(stderr, "shrunk buffer to %d\n", allocsize); 3429#endif 3430 } else { 3431 /* should we print a warning if couldn't return memory? */ 3432 v_buffer = v_bufstr - start; /* restore clobbered pointer */ 3433 } 3434 } 3435} 3436 3437#ifdef VMS 3438#define ptymask() (v_bufptr > v_bufstr ? pty_mask : 0) 3439 3440static void 3441in_put(XtermWidget xw) 3442{ 3443 static PtySelect select_mask; 3444 static PtySelect write_mask; 3445 int update = VTbuffer->update; 3446 int size; 3447 3448 int status; 3449 Dimension replyWidth, replyHeight; 3450 XtGeometryResult stat; 3451 3452 TScreen *screen = TScreenOf(xw); 3453 char *cp; 3454 int i; 3455 3456 select_mask = pty_mask; /* force initial read */ 3457 for (;;) { 3458 3459 /* if the terminal changed size, resize the widget */ 3460 if (tt_changed) { 3461 tt_changed = False; 3462 3463 stat = REQ_RESIZE((Widget) xw, 3464 ((Dimension) FontWidth(screen) 3465 * (tt_width) 3466 + 2 * screen->border 3467 + screen->fullVwin.sb_info.width), 3468 ((Dimension) FontHeight(screen) 3469 * (tt_length) 3470 + 2 * screen->border), 3471 &replyWidth, &replyHeight); 3472 3473 if (stat == XtGeometryYes || stat == XtGeometryDone) { 3474 xw->core.width = replyWidth; 3475 xw->core.height = replyHeight; 3476 3477 ScreenResize(xw, replyWidth, replyHeight, &xw->flags); 3478 } 3479 repairSizeHints(); 3480 } 3481 3482 if (screen->eventMode == NORMAL 3483 && readPtyData(xw, &select_mask, VTbuffer)) { 3484 if (screen->scrollWidget 3485 && screen->scrollttyoutput 3486 && screen->topline < 0) 3487 /* Scroll to bottom */ 3488 WindowScroll(xw, 0, False); 3489 break; 3490 } 3491 if (screen->scroll_amt) 3492 FlushScroll(xw); 3493 if (screen->cursor_set && CursorMoved(screen)) { 3494 if (screen->cursor_state) 3495 HideCursor(); 3496 ShowCursor(); 3497#if OPT_INPUT_METHOD 3498 PreeditPosition(screen); 3499#endif 3500 } else if (screen->cursor_set != screen->cursor_state) { 3501 if (screen->cursor_set) 3502 ShowCursor(); 3503 else 3504 HideCursor(); 3505 } 3506 3507 if (QLength(screen->display)) { 3508 select_mask = X_mask; 3509 } else { 3510 write_mask = ptymask(); 3511 XFlush(screen->display); 3512 select_mask = Select_mask; 3513 if (screen->eventMode != NORMAL) 3514 select_mask = X_mask; 3515 } 3516 if (write_mask & ptymask()) { 3517 v_write(screen->respond, 0, 0); /* flush buffer */ 3518 } 3519 3520 if (select_mask & X_mask) { 3521 xevents(); 3522 if (VTbuffer->update != update) 3523 break; 3524 } 3525 } 3526} 3527#else /* VMS */ 3528 3529static void 3530in_put(XtermWidget xw) 3531{ 3532 static PtySelect select_mask; 3533 static PtySelect write_mask; 3534 3535 TScreen *screen = TScreenOf(xw); 3536 int i, time_select; 3537 int size; 3538 int update = VTbuffer->update; 3539 3540 static struct timeval select_timeout; 3541 3542#if OPT_BLINK_CURS 3543 /* 3544 * Compute the timeout for the blinking cursor to be much smaller than 3545 * the "on" or "off" interval. 3546 */ 3547 int tick = ((screen->blink_on < screen->blink_off) 3548 ? screen->blink_on 3549 : screen->blink_off); 3550 tick *= (1000 / 8); /* 1000 for msec/usec, 8 for "much" smaller */ 3551 if (tick < 1) 3552 tick = 1; 3553#endif 3554 3555 for (;;) { 3556 if (screen->eventMode == NORMAL 3557 && (size = readPtyData(xw, &select_mask, VTbuffer)) != 0) { 3558 if (screen->scrollWidget 3559 && screen->scrollttyoutput 3560 && screen->topline < 0) 3561 WindowScroll(xw, 0, False); /* Scroll to bottom */ 3562 /* stop speed reading at some point to look for X stuff */ 3563 TRACE(("VTbuffer uses %ld/%d\n", 3564 (long) (VTbuffer->last - VTbuffer->buffer), 3565 BUF_SIZE)); 3566 if ((VTbuffer->last - VTbuffer->buffer) > BUF_SIZE) { 3567 FD_CLR(screen->respond, &select_mask); 3568 break; 3569 } 3570#if defined(HAVE_SCHED_YIELD) 3571 /* 3572 * If we've read a full (small/fragment) buffer, let the operating 3573 * system have a turn, and we'll resume reading until we've either 3574 * read only a fragment of the buffer, or we've filled the large 3575 * buffer (see above). Doing this helps keep up with large bursts 3576 * of output. 3577 */ 3578 if (size == FRG_SIZE) { 3579 select_timeout.tv_sec = 0; 3580 i = Select(max_plus1, &select_mask, &write_mask, 0, 3581 &select_timeout); 3582 if (i > 0) { 3583 sched_yield(); 3584 } else 3585 break; 3586 } else { 3587 break; 3588 } 3589#else 3590 (void) size; /* unused in this branch */ 3591 break; 3592#endif 3593 } 3594 /* update the screen */ 3595 if (screen->scroll_amt) 3596 FlushScroll(xw); 3597 if (screen->cursor_set && CursorMoved(screen)) { 3598 if (screen->cursor_state) 3599 HideCursor(); 3600 ShowCursor(); 3601#if OPT_INPUT_METHOD 3602 PreeditPosition(screen); 3603#endif 3604 } else if (screen->cursor_set != screen->cursor_state) { 3605 if (screen->cursor_set) 3606 ShowCursor(); 3607 else 3608 HideCursor(); 3609 } 3610 3611 XFlush(screen->display); /* always flush writes before waiting */ 3612 3613 /* Update the masks and, unless X events are already in the queue, 3614 wait for I/O to be possible. */ 3615 XFD_COPYSET(&Select_mask, &select_mask); 3616 /* in selection mode xterm does not read pty */ 3617 if (screen->eventMode != NORMAL) 3618 FD_CLR(screen->respond, &select_mask); 3619 3620 if (v_bufptr > v_bufstr) { 3621 XFD_COPYSET(&pty_mask, &write_mask); 3622 } else 3623 FD_ZERO(&write_mask); 3624 select_timeout.tv_sec = 0; 3625 time_select = 0; 3626 3627 /* 3628 * if there's either an XEvent or an XtTimeout pending, just take 3629 * a quick peek, i.e. timeout from the select() immediately. If 3630 * there's nothing pending, let select() block a little while, but 3631 * for a shorter interval than the arrow-style scrollbar timeout. 3632 * The blocking is optional, because it tends to increase the load 3633 * on the host. 3634 */ 3635 if (XtAppPending(app_con)) { 3636 select_timeout.tv_usec = 0; 3637 time_select = 1; 3638 } else if (screen->awaitInput) { 3639 select_timeout.tv_usec = 50000; 3640 time_select = 1; 3641#if OPT_BLINK_CURS 3642 } else if ((screen->blink_timer != 0 && 3643 ((screen->select & FOCUS) || screen->always_highlight)) || 3644 (screen->cursor_state == BLINKED_OFF)) { 3645 select_timeout.tv_usec = tick; 3646 while (select_timeout.tv_usec > 1000000) { 3647 select_timeout.tv_usec -= 1000000; 3648 select_timeout.tv_sec++; 3649 } 3650 time_select = 1; 3651#endif 3652#if OPT_SESSION_MGT 3653 } else if (resource.sessionMgt) { 3654 if (ice_fd >= 0) 3655 FD_SET(ice_fd, &select_mask); 3656#endif 3657 } 3658 if (need_cleanup) 3659 Cleanup(0); 3660 i = Select(max_plus1, &select_mask, &write_mask, 0, 3661 (time_select ? &select_timeout : 0)); 3662 if (i < 0) { 3663 if (errno != EINTR) 3664 SysError(ERROR_SELECT); 3665 continue; 3666 } 3667 3668 /* if there is room to write more data to the pty, go write more */ 3669 if (FD_ISSET(screen->respond, &write_mask)) { 3670 v_write(screen->respond, (Char *) 0, 0); /* flush buffer */ 3671 } 3672 3673 /* if there are X events already in our queue, it 3674 counts as being readable */ 3675 if (XtAppPending(app_con) || 3676 FD_ISSET(ConnectionNumber(screen->display), &select_mask)) { 3677 xevents(); 3678 if (VTbuffer->update != update) /* HandleInterpret */ 3679 break; 3680 } 3681 3682 } 3683} 3684#endif /* VMS */ 3685 3686static IChar 3687doinput(void) 3688{ 3689 TScreen *screen = TScreenOf(term); 3690 3691 while (!morePtyData(screen, VTbuffer)) 3692 in_put(term); 3693 return nextPtyData(screen, VTbuffer); 3694} 3695 3696#if OPT_INPUT_METHOD 3697/* 3698 * For OverTheSpot, client has to inform the position for XIM preedit. 3699 */ 3700static void 3701PreeditPosition(TScreen * screen) 3702{ 3703 LineData *ld; 3704 XPoint spot; 3705 XVaNestedList list; 3706 3707 if (screen->xic 3708 && (ld = getLineData(screen, screen->cur_row)) != 0) { 3709 spot.x = (short) LineCursorX(screen, ld, screen->cur_col); 3710 spot.y = (short) (CursorY(screen, screen->cur_row) + screen->fs_ascent); 3711 list = XVaCreateNestedList(0, 3712 XNSpotLocation, &spot, 3713 XNForeground, T_COLOR(screen, TEXT_FG), 3714 XNBackground, T_COLOR(screen, TEXT_BG), 3715 NULL); 3716 XSetICValues(screen->xic, XNPreeditAttributes, list, NULL); 3717 XFree(list); 3718 } 3719} 3720#endif 3721 3722static void 3723WrapLine(XtermWidget xw) 3724{ 3725 TScreen *screen = TScreenOf(xw); 3726 LineData *ld = getLineData(screen, screen->cur_row); 3727 3728 if (ld != 0) { 3729 /* mark that we had to wrap this line */ 3730 LineSetFlag(ld, LINEWRAPPED); 3731 if (screen->show_wrap_marks) { 3732 ShowWrapMarks(xw, screen->cur_row, ld); 3733 } 3734 xtermAutoPrint(xw, '\n'); 3735 xtermIndex(xw, 1); 3736 set_cur_col(screen, 0); 3737 } 3738} 3739 3740/* 3741 * process a string of characters according to the character set indicated 3742 * by charset. worry about end of line conditions (wraparound if selected). 3743 */ 3744void 3745dotext(XtermWidget xw, 3746 int charset, 3747 IChar * buf, /* start of characters to process */ 3748 Cardinal len) /* end */ 3749{ 3750 TScreen *screen = TScreenOf(xw); 3751#if OPT_WIDE_CHARS 3752 Cardinal chars_chomped = 1; 3753 int next_col = screen->cur_col; 3754#else 3755 int next_col, last_col, this_col; /* must be signed */ 3756#endif 3757 Cardinal offset; 3758 3759#if OPT_WIDE_CHARS 3760 /* don't translate if we use UTF-8, and are not handling legacy support 3761 * for line-drawing characters. 3762 */ 3763 if ((screen->utf8_mode == uFalse) 3764 || (screen->vt100_graphics)) 3765#endif 3766 if (!xtermCharSetOut(xw, buf, buf + len, charset)) 3767 return; 3768 3769 if_OPT_XMC_GLITCH(screen, { 3770 Cardinal n; 3771 if (charset != '?') { 3772 for (n = 0; n < len; n++) { 3773 if (buf[n] == XMC_GLITCH) 3774 buf[n] = XMC_GLITCH + 1; 3775 } 3776 } 3777 }); 3778 3779#if OPT_WIDE_CHARS 3780 for (offset = 0; 3781 offset < len && (chars_chomped > 0 || screen->do_wrap); 3782 offset += chars_chomped) { 3783 int width_available = MaxCols(screen) - screen->cur_col; 3784 int width_here = 0; 3785 Boolean need_wrap = False; 3786 int last_chomp = 0; 3787 chars_chomped = 0; 3788 3789 if (screen->do_wrap) { 3790 screen->do_wrap = False; 3791 if ((xw->flags & WRAPAROUND)) { 3792 WrapLine(xw); 3793 width_available = MaxCols(screen) - screen->cur_col; 3794 next_col = screen->cur_col; 3795 } 3796 } 3797 3798 while (width_here <= width_available && chars_chomped < (len - offset)) { 3799 if (!screen->utf8_mode 3800 || (screen->vt100_graphics && charset == '0')) 3801 last_chomp = 1; 3802 else 3803 last_chomp = my_wcwidth((int) buf[chars_chomped + offset]); 3804 width_here += last_chomp; 3805 chars_chomped++; 3806 } 3807 3808 if (width_here > width_available) { 3809 if (last_chomp > MaxCols(screen)) 3810 break; /* give up - it is too big */ 3811 chars_chomped--; 3812 width_here -= last_chomp; 3813 if (chars_chomped > 0) { 3814 need_wrap = True; 3815 } 3816 } else if (width_here == width_available) { 3817 need_wrap = True; 3818 } else if (chars_chomped != (len - offset)) { 3819 need_wrap = True; 3820 } 3821 3822 /* 3823 * Split the wide characters back into separate arrays of 8-bit 3824 * characters so we can use the existing interface. 3825 * 3826 * FIXME: If we rewrote this interface, it would involve 3827 * rewriting all of the memory-management for the screen 3828 * buffers (perhaps this is simpler). 3829 */ 3830 if (chars_chomped != 0 && next_col <= screen->max_col) { 3831 WriteText(xw, buf + offset, chars_chomped); 3832 } 3833 next_col += width_here; 3834 screen->do_wrap = need_wrap; 3835 } 3836#else /* ! OPT_WIDE_CHARS */ 3837 3838 for (offset = 0; offset < len; offset += (Cardinal) this_col) { 3839#if OPT_DEC_CHRSET 3840 LineData *ld = getLineData(screen, screen->cur_row); 3841#endif 3842 3843 last_col = LineMaxCol(screen, ld); 3844 this_col = last_col - screen->cur_col + 1; 3845 if (this_col <= 1) { 3846 if (screen->do_wrap) { 3847 screen->do_wrap = False; 3848 if ((xw->flags & WRAPAROUND)) { 3849 WrapLine(xw); 3850 } 3851 } 3852 this_col = 1; 3853 } 3854 if (offset + (Cardinal) this_col > len) { 3855 this_col = (int) (len - offset); 3856 } 3857 next_col = screen->cur_col + this_col; 3858 3859 WriteText(xw, buf + offset, (unsigned) this_col); 3860 3861 /* 3862 * The call to WriteText updates screen->cur_col. 3863 * If screen->cur_col is less than next_col, we must have 3864 * hit the right margin - so set the do_wrap flag. 3865 */ 3866 screen->do_wrap = (Boolean) (screen->cur_col < next_col); 3867 } 3868 3869#endif /* OPT_WIDE_CHARS */ 3870} 3871 3872#if OPT_WIDE_CHARS 3873unsigned 3874visual_width(IChar * str, Cardinal len) 3875{ 3876 /* returns the visual width of a string (doublewide characters count 3877 as 2, normalwide characters count as 1) */ 3878 unsigned my_len = 0; 3879 while (len) { 3880 int ch = (int) *str++; 3881 if (isWide(ch)) 3882 my_len += 2; 3883 else 3884 my_len++; 3885 len--; 3886 } 3887 return my_len; 3888} 3889#endif 3890 3891#if HANDLE_STRUCT_NOTIFY 3892/* Flag icon name with "***" on window output when iconified. 3893 */ 3894static void 3895HandleStructNotify(Widget w GCC_UNUSED, 3896 XtPointer closure GCC_UNUSED, 3897 XEvent * event, 3898 Boolean * cont GCC_UNUSED) 3899{ 3900 static char *icon_name; 3901 static Arg args[] = 3902 { 3903 {XtNiconName, (XtArgVal) & icon_name} 3904 }; 3905 XtermWidget xw = term; 3906 TScreen *screen = TScreenOf(xw); 3907 3908 switch (event->type) { 3909 case MapNotify: 3910 TRACE(("HandleStructNotify(MapNotify)\n")); 3911#if OPT_ZICONBEEP 3912 if (screen->zIconBeep_flagged) { 3913 screen->zIconBeep_flagged = False; 3914 icon_name = NULL; 3915 XtGetValues(toplevel, args, XtNumber(args)); 3916 if (icon_name != NULL) { 3917 char *buf = CastMallocN(char, strlen(icon_name)); 3918 if (buf == NULL) { 3919 screen->zIconBeep_flagged = True; 3920 return; 3921 } 3922 strcpy(buf, icon_name + 4); 3923 ChangeIconName(xw, buf); 3924 free(buf); 3925 } 3926 } 3927#endif /* OPT_ZICONBEEP */ 3928 mapstate = !IsUnmapped; 3929 break; 3930 case UnmapNotify: 3931 TRACE(("HandleStructNotify(UnmapNotify)\n")); 3932 mapstate = IsUnmapped; 3933 break; 3934 case ConfigureNotify: 3935 if (event->xconfigure.window == XtWindow(toplevel)) { 3936#if !OPT_TOOLBAR 3937 int height, width; 3938 3939 height = event->xconfigure.height; 3940 width = event->xconfigure.width; 3941#endif 3942 TRACE(("HandleStructNotify(ConfigureNotify) %d,%d %dx%d\n", 3943 event->xconfigure.y, event->xconfigure.x, 3944 event->xconfigure.height, event->xconfigure.width)); 3945 3946#if OPT_TOOLBAR 3947 /* 3948 * The notification is for the top-level widget, but we care about 3949 * vt100 (ignore the tek4014 window). 3950 */ 3951 if (TScreenOf(xw)->Vshow) { 3952 VTwin *Vwin = WhichVWin(TScreenOf(xw)); 3953 TbInfo *info = &(Vwin->tb_info); 3954 TbInfo save = *info; 3955 3956 if (info->menu_bar) { 3957 XtVaGetValues(info->menu_bar, 3958 XtNheight, &info->menu_height, 3959 XtNborderWidth, &info->menu_border, 3960 (XtPointer) 0); 3961 3962 if (save.menu_height != info->menu_height 3963 || save.menu_border != info->menu_border) { 3964 3965 TRACE(("...menu_height %d\n", info->menu_height)); 3966 TRACE(("...menu_border %d\n", info->menu_border)); 3967 TRACE(("...had height %d, border %d\n", 3968 save.menu_height, 3969 save.menu_border)); 3970 3971 /* 3972 * FIXME: Window manager still may be using the old 3973 * values. Try to fool it. 3974 */ 3975 REQ_RESIZE((Widget) xw, 3976 screen->fullVwin.fullwidth, 3977 (Dimension) (info->menu_height 3978 - save.menu_height 3979 + screen->fullVwin.fullheight), 3980 NULL, NULL); 3981 repairSizeHints(); 3982 } 3983 } 3984 } 3985#else 3986 if (height != xw->hints.height || width != xw->hints.width) 3987 RequestResize(xw, height, width, False); 3988#endif /* OPT_TOOLBAR */ 3989 } 3990 break; 3991 case ReparentNotify: 3992 TRACE(("HandleStructNotify(ReparentNotify)\n")); 3993 break; 3994 default: 3995 TRACE(("HandleStructNotify(event %s)\n", 3996 visibleEventType(event->type))); 3997 break; 3998 } 3999} 4000#endif /* HANDLE_STRUCT_NOTIFY */ 4001 4002#if OPT_BLINK_CURS 4003static void 4004SetCursorBlink(TScreen * screen, Bool enable) 4005{ 4006 screen->cursor_blink = (Boolean) enable; 4007 if (DoStartBlinking(screen)) { 4008 StartBlinking(screen); 4009 } else { 4010 /* EMPTY */ 4011#if !OPT_BLINK_TEXT 4012 StopBlinking(screen); 4013#endif 4014 } 4015 update_cursorblink(); 4016} 4017 4018void 4019ToggleCursorBlink(TScreen * screen) 4020{ 4021 SetCursorBlink(screen, (Bool) (!(screen->cursor_blink))); 4022} 4023#endif 4024 4025/* 4026 * process ANSI modes set, reset 4027 */ 4028static void 4029ansi_modes(XtermWidget xw, BitFunc func) 4030{ 4031 int i; 4032 4033 for (i = 0; i < nparam; ++i) { 4034 switch (param[i]) { 4035 case 2: /* KAM (if set, keyboard locked */ 4036 (*func) (&xw->keyboard.flags, MODE_KAM); 4037 break; 4038 4039 case 4: /* IRM */ 4040 (*func) (&xw->flags, INSERT); 4041 break; 4042 4043 case 12: /* SRM (if set, local echo */ 4044 (*func) (&xw->keyboard.flags, MODE_SRM); 4045 break; 4046 4047 case 20: /* LNM */ 4048 (*func) (&xw->flags, LINEFEED); 4049 update_autolinefeed(); 4050 break; 4051 } 4052 } 4053} 4054 4055#define IsSM() (func == bitset) 4056 4057#define set_bool_mode(flag) \ 4058 flag = (Boolean) IsSM() 4059 4060static void 4061really_set_mousemode(XtermWidget xw, 4062 Bool enabled, 4063 XtermMouseModes mode) 4064{ 4065 TScreenOf(xw)->send_mouse_pos = enabled ? mode : MOUSE_OFF; 4066 if (TScreenOf(xw)->send_mouse_pos != MOUSE_OFF) 4067 xtermShowPointer(xw, True); 4068} 4069 4070#define set_mousemode(mode) really_set_mousemode(xw, IsSM(), mode) 4071 4072#if OPT_READLINE 4073#define set_mouseflag(f) \ 4074 (IsSM() \ 4075 ? SCREEN_FLAG_set(screen, f) \ 4076 : SCREEN_FLAG_unset(screen, f)) 4077#endif 4078 4079/* 4080 * process DEC private modes set, reset 4081 */ 4082static void 4083dpmodes(XtermWidget xw, BitFunc func) 4084{ 4085 TScreen *screen = TScreenOf(xw); 4086 int i, j; 4087 unsigned myflags; 4088 4089 for (i = 0; i < nparam; ++i) { 4090 TRACE(("%s %d\n", IsSM()? "DECSET" : "DECRST", param[i])); 4091 switch (param[i]) { 4092 case 1: /* DECCKM */ 4093 (*func) (&xw->keyboard.flags, MODE_DECCKM); 4094 update_appcursor(); 4095 break; 4096 case 2: /* DECANM - ANSI/VT52 mode */ 4097 if (IsSM()) { /* ANSI (VT100) */ 4098 /* 4099 * Setting DECANM should have no effect, since this function 4100 * cannot be reached from vt52 mode. 4101 */ 4102 /* EMPTY */ ; 4103 } 4104#if OPT_VT52_MODE 4105 else if (screen->terminal_id >= 100) { /* VT52 */ 4106 TRACE(("DECANM terminal_id %d, vtXX_level %d\n", 4107 screen->terminal_id, 4108 screen->vtXX_level)); 4109 screen->vt52_save_level = screen->vtXX_level; 4110 screen->vtXX_level = 0; 4111 screen->vt52_save_curgl = screen->curgl; 4112 screen->vt52_save_curgr = screen->curgr; 4113 screen->vt52_save_curss = screen->curss; 4114 memmove(screen->vt52_save_gsets, screen->gsets, sizeof(screen->gsets)); 4115 resetCharsets(screen); 4116 nparam = 0; /* ignore the remaining params, if any */ 4117 } 4118#endif 4119 break; 4120 case 3: /* DECCOLM */ 4121 if (screen->c132) { 4122 ClearScreen(xw); 4123 CursorSet(screen, 0, 0, xw->flags); 4124 if ((j = IsSM()? 132 : 80) != 4125 ((xw->flags & IN132COLUMNS) ? 132 : 80) || 4126 j != MaxCols(screen)) 4127 RequestResize(xw, -1, j, True); 4128 (*func) (&xw->flags, IN132COLUMNS); 4129 } 4130 break; 4131 case 4: /* DECSCLM (slow scroll) */ 4132 if (IsSM()) { 4133 screen->jumpscroll = 0; 4134 if (screen->scroll_amt) 4135 FlushScroll(xw); 4136 } else 4137 screen->jumpscroll = 1; 4138 (*func) (&xw->flags, SMOOTHSCROLL); 4139 update_jumpscroll(); 4140 break; 4141 case 5: /* DECSCNM */ 4142 myflags = xw->flags; 4143 (*func) (&xw->flags, REVERSE_VIDEO); 4144 if ((xw->flags ^ myflags) & REVERSE_VIDEO) 4145 ReverseVideo(xw); 4146 /* update_reversevideo done in RevVid */ 4147 break; 4148 4149 case 6: /* DECOM */ 4150 (*func) (&xw->flags, ORIGIN); 4151 CursorSet(screen, 0, 0, xw->flags); 4152 break; 4153 4154 case 7: /* DECAWM */ 4155 (*func) (&xw->flags, WRAPAROUND); 4156 update_autowrap(); 4157 break; 4158 case 8: /* DECARM */ 4159 /* ignore autorepeat 4160 * XAutoRepeatOn() and XAutoRepeatOff() can do this, but only 4161 * for the whole display - not limited to a given window. 4162 */ 4163 break; 4164 case SET_X10_MOUSE: /* MIT bogus sequence */ 4165 MotionOff(screen, xw); 4166 set_mousemode(X10_MOUSE); 4167 break; 4168#if OPT_TOOLBAR 4169 case 10: /* rxvt */ 4170 ShowToolbar(IsSM()); 4171 break; 4172#endif 4173#if OPT_BLINK_CURS 4174 case 12: /* att610: Start/stop blinking cursor */ 4175 if (screen->cursor_blink_res) { 4176 set_bool_mode(screen->cursor_blink_esc); 4177 SetCursorBlink(screen, screen->cursor_blink); 4178 } 4179 break; 4180#endif 4181 case 18: /* DECPFF: print form feed */ 4182 set_bool_mode(screen->printer_formfeed); 4183 break; 4184 case 19: /* DECPEX: print extent */ 4185 set_bool_mode(screen->printer_extent); 4186 break; 4187 case 25: /* DECTCEM: Show/hide cursor (VT200) */ 4188 set_bool_mode(screen->cursor_set); 4189 break; 4190 case 30: /* rxvt */ 4191 if (screen->fullVwin.sb_info.width != (IsSM()? ON : OFF)) 4192 ToggleScrollBar(xw); 4193 break; 4194#if OPT_SHIFT_FONTS 4195 case 35: /* rxvt */ 4196 set_bool_mode(xw->misc.shift_fonts); 4197 break; 4198#endif 4199 case 38: /* DECTEK */ 4200#if OPT_TEK4014 4201 if (IsSM() && !(screen->inhibit & I_TEK)) { 4202 FlushLog(xw); 4203 TEK4014_ACTIVE(xw) = True; 4204 } 4205#endif 4206 break; 4207 case 40: /* 132 column mode */ 4208 set_bool_mode(screen->c132); 4209 update_allow132(); 4210 break; 4211 case 41: /* curses hack */ 4212 set_bool_mode(screen->curses); 4213 update_cursesemul(); 4214 break; 4215 case 42: /* DECNRCM national charset (VT220) */ 4216 (*func) (&xw->flags, NATIONAL); 4217 break; 4218 case 44: /* margin bell */ 4219 set_bool_mode(screen->marginbell); 4220 if (!screen->marginbell) 4221 screen->bellArmed = -1; 4222 update_marginbell(); 4223 break; 4224 case 45: /* reverse wraparound */ 4225 (*func) (&xw->flags, REVERSEWRAP); 4226 update_reversewrap(); 4227 break; 4228#ifdef ALLOWLOGGING 4229 case 46: /* logging */ 4230#ifdef ALLOWLOGFILEONOFF 4231 /* 4232 * if this feature is enabled, logging may be 4233 * enabled and disabled via escape sequences. 4234 */ 4235 if (IsSM()) 4236 StartLog(xw); 4237 else 4238 CloseLog(xw); 4239#else 4240 Bell(xw, XkbBI_Info, 0); 4241 Bell(xw, XkbBI_Info, 0); 4242#endif /* ALLOWLOGFILEONOFF */ 4243 break; 4244#endif 4245 case 1049: /* alternate buffer & cursor */ 4246 if (!xw->misc.titeInhibit) { 4247 if (IsSM()) { 4248 CursorSave(xw); 4249 ToAlternate(xw); 4250 ClearScreen(xw); 4251 } else { 4252 FromAlternate(xw); 4253 CursorRestore(xw); 4254 } 4255 } else if (xw->misc.tiXtraScroll) { 4256 if (IsSM()) { 4257 xtermScroll(xw, screen->max_row); 4258 } 4259 } 4260 break; 4261 case 1047: 4262 /* FALLTHRU */ 4263 case 47: /* alternate buffer */ 4264 if (!xw->misc.titeInhibit) { 4265 if (IsSM()) { 4266 ToAlternate(xw); 4267 } else { 4268 if (screen->whichBuf 4269 && (param[i] == 1047)) 4270 ClearScreen(xw); 4271 FromAlternate(xw); 4272 } 4273 } else if (xw->misc.tiXtraScroll) { 4274 if (IsSM()) { 4275 xtermScroll(xw, screen->max_row); 4276 } 4277 } 4278 break; 4279 case 66: /* DECNKM */ 4280 (*func) (&xw->keyboard.flags, MODE_DECKPAM); 4281 update_appkeypad(); 4282 break; 4283 case 67: /* DECBKM */ 4284 /* back-arrow mapped to backspace or delete(D) */ 4285 (*func) (&xw->keyboard.flags, MODE_DECBKM); 4286 TRACE(("DECSET DECBKM %s\n", 4287 BtoS(xw->keyboard.flags & MODE_DECBKM))); 4288 update_decbkm(); 4289 break; 4290 case SET_VT200_MOUSE: /* xterm bogus sequence */ 4291 MotionOff(screen, xw); 4292 set_mousemode(VT200_MOUSE); 4293 break; 4294 case SET_VT200_HIGHLIGHT_MOUSE: /* xterm sequence w/hilite tracking */ 4295 MotionOff(screen, xw); 4296 set_mousemode(VT200_HIGHLIGHT_MOUSE); 4297 break; 4298 case SET_BTN_EVENT_MOUSE: 4299 MotionOff(screen, xw); 4300 set_mousemode(BTN_EVENT_MOUSE); 4301 break; 4302 case SET_ANY_EVENT_MOUSE: 4303 set_mousemode(ANY_EVENT_MOUSE); 4304 if (screen->send_mouse_pos == MOUSE_OFF) { 4305 MotionOff(screen, xw); 4306 } else { 4307 MotionOn(screen, xw); 4308 } 4309 break; 4310#if OPT_FOCUS_EVENT 4311 case SET_FOCUS_EVENT_MOUSE: 4312 set_bool_mode(screen->send_focus_pos); 4313 break; 4314#endif 4315 case SET_EXT_MODE_MOUSE: 4316 set_bool_mode(screen->ext_mode_mouse); 4317 break; 4318 case 1010: /* rxvt */ 4319 set_bool_mode(screen->scrollttyoutput); 4320 update_scrollttyoutput(); 4321 break; 4322 case 1011: /* rxvt */ 4323 set_bool_mode(screen->scrollkey); 4324 update_scrollkey(); 4325 break; 4326 case 1034: 4327 set_bool_mode(screen->input_eight_bits); 4328 update_alt_esc(); 4329 break; 4330#if OPT_NUM_LOCK 4331 case 1035: 4332 set_bool_mode(xw->misc.real_NumLock); 4333 update_num_lock(); 4334 break; 4335 case 1036: 4336 set_bool_mode(screen->meta_sends_esc); 4337 update_meta_esc(); 4338 break; 4339#endif 4340 case 1037: 4341 set_bool_mode(screen->delete_is_del); 4342 update_delete_del(); 4343 break; 4344#if OPT_NUM_LOCK 4345 case 1039: 4346 set_bool_mode(screen->alt_sends_esc); 4347 update_alt_esc(); 4348 break; 4349#endif 4350 case 1040: 4351 set_bool_mode(screen->keepSelection); 4352 update_keepSelection(); 4353 break; 4354 case 1041: 4355 set_bool_mode(screen->selectToClipboard); 4356 update_selectToClipboard(); 4357 break; 4358 case 1042: 4359 set_bool_mode(screen->bellIsUrgent); 4360 update_bellIsUrgent(); 4361 break; 4362 case 1043: 4363 set_bool_mode(screen->poponbell); 4364 update_poponbell(); 4365 break; 4366 case 1048: 4367 if (!xw->misc.titeInhibit) { 4368 if (IsSM()) 4369 CursorSave(xw); 4370 else 4371 CursorRestore(xw); 4372 } 4373 break; 4374#if OPT_TCAP_FKEYS 4375 case 1050: 4376 set_keyboard_type(xw, keyboardIsTermcap, IsSM()); 4377 break; 4378#endif 4379#if OPT_SUN_FUNC_KEYS 4380 case 1051: 4381 set_keyboard_type(xw, keyboardIsSun, IsSM()); 4382 break; 4383#endif 4384#if OPT_HP_FUNC_KEYS 4385 case 1052: 4386 set_keyboard_type(xw, keyboardIsHP, IsSM()); 4387 break; 4388#endif 4389#if OPT_SCO_FUNC_KEYS 4390 case 1053: 4391 set_keyboard_type(xw, keyboardIsSCO, IsSM()); 4392 break; 4393#endif 4394 case 1060: 4395 set_keyboard_type(xw, keyboardIsLegacy, IsSM()); 4396 break; 4397#if OPT_SUNPC_KBD 4398 case 1061: 4399 set_keyboard_type(xw, keyboardIsVT220, IsSM()); 4400 break; 4401#endif 4402#if OPT_READLINE 4403 case SET_BUTTON1_MOVE_POINT: 4404 set_mouseflag(click1_moves); 4405 break; 4406 case SET_BUTTON2_MOVE_POINT: 4407 set_mouseflag(paste_moves); 4408 break; 4409 case SET_DBUTTON3_DELETE: 4410 set_mouseflag(dclick3_deletes); 4411 break; 4412 case SET_PASTE_IN_BRACKET: 4413 set_mouseflag(paste_brackets); 4414 break; 4415 case SET_PASTE_QUOTE: 4416 set_mouseflag(paste_quotes); 4417 break; 4418 case SET_PASTE_LITERAL_NL: 4419 set_mouseflag(paste_literal_nl); 4420 break; 4421#endif /* OPT_READLINE */ 4422 } 4423 } 4424} 4425 4426/* 4427 * process xterm private modes save 4428 */ 4429static void 4430savemodes(XtermWidget xw) 4431{ 4432 TScreen *screen = TScreenOf(xw); 4433 int i; 4434 4435 for (i = 0; i < nparam; i++) { 4436 TRACE(("savemodes %d\n", param[i])); 4437 switch (param[i]) { 4438 case 1: /* DECCKM */ 4439 DoSM(DP_DECCKM, xw->keyboard.flags & MODE_DECCKM); 4440 break; 4441 case 3: /* DECCOLM */ 4442 if (screen->c132) 4443 DoSM(DP_DECCOLM, xw->flags & IN132COLUMNS); 4444 break; 4445 case 4: /* DECSCLM (slow scroll) */ 4446 DoSM(DP_DECSCLM, xw->flags & SMOOTHSCROLL); 4447 break; 4448 case 5: /* DECSCNM */ 4449 DoSM(DP_DECSCNM, xw->flags & REVERSE_VIDEO); 4450 break; 4451 case 6: /* DECOM */ 4452 DoSM(DP_DECOM, xw->flags & ORIGIN); 4453 break; 4454 case 7: /* DECAWM */ 4455 DoSM(DP_DECAWM, xw->flags & WRAPAROUND); 4456 break; 4457 case 8: /* DECARM */ 4458 /* ignore autorepeat */ 4459 break; 4460 case SET_X10_MOUSE: /* mouse bogus sequence */ 4461 DoSM(DP_X_X10MSE, screen->send_mouse_pos); 4462 break; 4463#if OPT_TOOLBAR 4464 case 10: /* rxvt */ 4465 DoSM(DP_TOOLBAR, resource.toolBar); 4466 break; 4467#endif 4468#if OPT_BLINK_CURS 4469 case 12: /* att610: Start/stop blinking cursor */ 4470 if (screen->cursor_blink_res) { 4471 DoSM(DP_CRS_BLINK, screen->cursor_blink_esc); 4472 } 4473 break; 4474#endif 4475 case 18: /* DECPFF: print form feed */ 4476 DoSM(DP_PRN_FORMFEED, screen->printer_formfeed); 4477 break; 4478 case 19: /* DECPEX: print extent */ 4479 DoSM(DP_PRN_EXTENT, screen->printer_extent); 4480 break; 4481 case 25: /* DECTCEM: Show/hide cursor (VT200) */ 4482 DoSM(DP_CRS_VISIBLE, screen->cursor_set); 4483 break; 4484 case 40: /* 132 column mode */ 4485 DoSM(DP_X_DECCOLM, screen->c132); 4486 break; 4487 case 41: /* curses hack */ 4488 DoSM(DP_X_MORE, screen->curses); 4489 break; 4490 case 42: /* DECNRCM national charset (VT220) */ 4491 /* do nothing */ 4492 break; 4493 case 44: /* margin bell */ 4494 DoSM(DP_X_MARGIN, screen->marginbell); 4495 break; 4496 case 45: /* reverse wraparound */ 4497 DoSM(DP_X_REVWRAP, xw->flags & REVERSEWRAP); 4498 break; 4499#ifdef ALLOWLOGGING 4500 case 46: /* logging */ 4501 DoSM(DP_X_LOGGING, screen->logging); 4502 break; 4503#endif 4504 case 1047: /* alternate buffer */ 4505 /* FALLTHRU */ 4506 case 47: /* alternate buffer */ 4507 DoSM(DP_X_ALTSCRN, screen->whichBuf); 4508 break; 4509 case SET_VT200_MOUSE: /* mouse bogus sequence */ 4510 case SET_VT200_HIGHLIGHT_MOUSE: 4511 case SET_BTN_EVENT_MOUSE: 4512 case SET_ANY_EVENT_MOUSE: 4513 DoSM(DP_X_MOUSE, screen->send_mouse_pos); 4514 break; 4515#if OPT_FOCUS_EVENT 4516 case SET_FOCUS_EVENT_MOUSE: 4517 DoSM(DP_X_FOCUS, screen->send_focus_pos); 4518 break; 4519#endif 4520 case SET_EXT_MODE_MOUSE: 4521 DoSM(DP_X_EXT_MOUSE, screen->ext_mode_mouse); 4522 break; 4523 case 1048: 4524 if (!xw->misc.titeInhibit) { 4525 CursorSave(xw); 4526 } 4527 break; 4528#if OPT_READLINE 4529 case SET_BUTTON1_MOVE_POINT: 4530 SCREEN_FLAG_save(screen, click1_moves); 4531 break; 4532 case SET_BUTTON2_MOVE_POINT: 4533 SCREEN_FLAG_save(screen, paste_moves); 4534 break; 4535 case SET_DBUTTON3_DELETE: 4536 SCREEN_FLAG_save(screen, dclick3_deletes); 4537 break; 4538 case SET_PASTE_IN_BRACKET: 4539 SCREEN_FLAG_save(screen, paste_brackets); 4540 break; 4541 case SET_PASTE_QUOTE: 4542 SCREEN_FLAG_save(screen, paste_quotes); 4543 break; 4544 case SET_PASTE_LITERAL_NL: 4545 SCREEN_FLAG_save(screen, paste_literal_nl); 4546 break; 4547#endif /* OPT_READLINE */ 4548 } 4549 } 4550} 4551 4552/* 4553 * process xterm private modes restore 4554 */ 4555static void 4556restoremodes(XtermWidget xw) 4557{ 4558 TScreen *screen = TScreenOf(xw); 4559 int i, j; 4560 4561 for (i = 0; i < nparam; i++) { 4562 TRACE(("restoremodes %d\n", param[i])); 4563 switch (param[i]) { 4564 case 1: /* DECCKM */ 4565 bitcpy(&xw->keyboard.flags, 4566 screen->save_modes[DP_DECCKM], MODE_DECCKM); 4567 update_appcursor(); 4568 break; 4569 case 3: /* DECCOLM */ 4570 if (screen->c132) { 4571 ClearScreen(xw); 4572 CursorSet(screen, 0, 0, xw->flags); 4573 if ((j = (screen->save_modes[DP_DECCOLM] & IN132COLUMNS) 4574 ? 132 : 80) != ((xw->flags & IN132COLUMNS) 4575 ? 132 : 80) || j != MaxCols(screen)) 4576 RequestResize(xw, -1, j, True); 4577 bitcpy(&xw->flags, 4578 screen->save_modes[DP_DECCOLM], 4579 IN132COLUMNS); 4580 } 4581 break; 4582 case 4: /* DECSCLM (slow scroll) */ 4583 if (screen->save_modes[DP_DECSCLM] & SMOOTHSCROLL) { 4584 screen->jumpscroll = 0; 4585 if (screen->scroll_amt) 4586 FlushScroll(xw); 4587 } else 4588 screen->jumpscroll = 1; 4589 bitcpy(&xw->flags, screen->save_modes[DP_DECSCLM], SMOOTHSCROLL); 4590 update_jumpscroll(); 4591 break; 4592 case 5: /* DECSCNM */ 4593 if ((screen->save_modes[DP_DECSCNM] ^ xw->flags) & REVERSE_VIDEO) { 4594 bitcpy(&xw->flags, screen->save_modes[DP_DECSCNM], REVERSE_VIDEO); 4595 ReverseVideo(xw); 4596 /* update_reversevideo done in RevVid */ 4597 } 4598 break; 4599 case 6: /* DECOM */ 4600 bitcpy(&xw->flags, screen->save_modes[DP_DECOM], ORIGIN); 4601 CursorSet(screen, 0, 0, xw->flags); 4602 break; 4603 4604 case 7: /* DECAWM */ 4605 bitcpy(&xw->flags, screen->save_modes[DP_DECAWM], WRAPAROUND); 4606 update_autowrap(); 4607 break; 4608 case 8: /* DECARM */ 4609 /* ignore autorepeat */ 4610 break; 4611 case SET_X10_MOUSE: /* MIT bogus sequence */ 4612 DoRM0(DP_X_X10MSE, screen->send_mouse_pos); 4613 break; 4614#if OPT_TOOLBAR 4615 case 10: /* rxvt */ 4616 DoRM(DP_TOOLBAR, resource.toolBar); 4617 ShowToolbar(resource.toolBar); 4618 break; 4619#endif 4620#if OPT_BLINK_CURS 4621 case 12: /* att610: Start/stop blinking cursor */ 4622 if (screen->cursor_blink_res) { 4623 DoRM(DP_CRS_BLINK, screen->cursor_blink_esc); 4624 SetCursorBlink(screen, screen->cursor_blink); 4625 } 4626 break; 4627#endif 4628 case 18: /* DECPFF: print form feed */ 4629 DoRM(DP_PRN_FORMFEED, screen->printer_formfeed); 4630 break; 4631 case 19: /* DECPEX: print extent */ 4632 DoRM(DP_PRN_EXTENT, screen->printer_extent); 4633 break; 4634 case 25: /* DECTCEM: Show/hide cursor (VT200) */ 4635 DoRM(DP_CRS_VISIBLE, screen->cursor_set); 4636 break; 4637 case 40: /* 132 column mode */ 4638 DoRM(DP_X_DECCOLM, screen->c132); 4639 update_allow132(); 4640 break; 4641 case 41: /* curses hack */ 4642 DoRM(DP_X_MORE, screen->curses); 4643 update_cursesemul(); 4644 break; 4645 case 44: /* margin bell */ 4646 if ((DoRM(DP_X_MARGIN, screen->marginbell)) == 0) 4647 screen->bellArmed = -1; 4648 update_marginbell(); 4649 break; 4650 case 45: /* reverse wraparound */ 4651 bitcpy(&xw->flags, screen->save_modes[DP_X_REVWRAP], REVERSEWRAP); 4652 update_reversewrap(); 4653 break; 4654#ifdef ALLOWLOGGING 4655 case 46: /* logging */ 4656#ifdef ALLOWLOGFILEONOFF 4657 if (screen->save_modes[DP_X_LOGGING]) 4658 StartLog(xw); 4659 else 4660 CloseLog(xw); 4661#endif /* ALLOWLOGFILEONOFF */ 4662 /* update_logging done by StartLog and CloseLog */ 4663 break; 4664#endif 4665 case 1047: /* alternate buffer */ 4666 /* FALLTHRU */ 4667 case 47: /* alternate buffer */ 4668 if (!xw->misc.titeInhibit) { 4669 if (screen->save_modes[DP_X_ALTSCRN]) 4670 ToAlternate(xw); 4671 else 4672 FromAlternate(xw); 4673 /* update_altscreen done by ToAlt and FromAlt */ 4674 } else if (xw->misc.tiXtraScroll) { 4675 if (screen->save_modes[DP_X_ALTSCRN]) { 4676 xtermScroll(xw, screen->max_row); 4677 } 4678 } 4679 break; 4680 case SET_VT200_MOUSE: /* mouse bogus sequence */ 4681 case SET_VT200_HIGHLIGHT_MOUSE: 4682 case SET_BTN_EVENT_MOUSE: 4683 case SET_ANY_EVENT_MOUSE: 4684 DoRM0(DP_X_MOUSE, screen->send_mouse_pos); 4685 break; 4686#if OPT_FOCUS_EVENT 4687 case SET_FOCUS_EVENT_MOUSE: 4688 DoRM(DP_X_FOCUS, screen->send_focus_pos); 4689 break; 4690#endif 4691 case SET_EXT_MODE_MOUSE: 4692 DoRM(DP_X_EXT_MOUSE, screen->ext_mode_mouse); 4693 break; 4694 case 1048: 4695 if (!xw->misc.titeInhibit) { 4696 CursorRestore(xw); 4697 } 4698 break; 4699#if OPT_READLINE 4700 case SET_BUTTON1_MOVE_POINT: 4701 SCREEN_FLAG_restore(screen, click1_moves); 4702 break; 4703 case SET_BUTTON2_MOVE_POINT: 4704 SCREEN_FLAG_restore(screen, paste_moves); 4705 break; 4706 case SET_DBUTTON3_DELETE: 4707 SCREEN_FLAG_restore(screen, dclick3_deletes); 4708 break; 4709 case SET_PASTE_IN_BRACKET: 4710 SCREEN_FLAG_restore(screen, paste_brackets); 4711 break; 4712 case SET_PASTE_QUOTE: 4713 SCREEN_FLAG_restore(screen, paste_quotes); 4714 break; 4715 case SET_PASTE_LITERAL_NL: 4716 SCREEN_FLAG_restore(screen, paste_literal_nl); 4717 break; 4718#endif /* OPT_READLINE */ 4719 } 4720 } 4721} 4722 4723/* 4724 * Convert an XTextProperty to a string. 4725 * 4726 * This frees the data owned by the XTextProperty, and returns in its place the 4727 * string, which must be freed by the caller. 4728 */ 4729static char * 4730property_to_string(XtermWidget xw, XTextProperty * text) 4731{ 4732 TScreen *screen = TScreenOf(xw); 4733 Display *dpy = screen->display; 4734 char *result = 0; 4735 char **list; 4736 int length = 0; 4737 int rc; 4738 4739 TRACE(("property_to_string value %p, encoding %s, format %d, nitems %ld\n", 4740 text->value, 4741 XGetAtomName(dpy, text->encoding), 4742 text->format, 4743 text->nitems)); 4744 4745#if OPT_WIDE_CHARS 4746 /* 4747 * We will use the XmbTextPropertyToTextList call to extract UTF-8 data. 4748 * The xtermUtf8ToTextList() call is used to convert UTF-8 explicitly to 4749 * ISO-8859-1. 4750 */ 4751 if ((text->format != 8) 4752 || IsTitleMode(xw, tmGetUtf8) 4753 || (rc = xtermUtf8ToTextList(xw, text, &list, &length)) < 0) 4754#endif 4755 if ((rc = XmbTextPropertyToTextList(dpy, text, &list, &length)) < 0) 4756 rc = XTextPropertyToStringList(text, &list, &length); 4757 4758 if (rc >= 0) { 4759 int n, c, pass; 4760 size_t need = 0; 4761 4762 for (pass = 0; pass < 2; ++pass) { 4763 for (n = 0, need = 0; n < length; n++) { 4764 char *s = list[n]; 4765 while ((c = *s++) != '\0') { 4766 if (pass) 4767 result[need] = (char) c; 4768 ++need; 4769 } 4770 } 4771 if (pass) 4772 result[need] = '\0'; 4773 else 4774 result = malloc(need + 1); 4775 if (result == 0) 4776 break; 4777 } 4778 XFreeStringList(list); 4779 } 4780 if (text->value != 0) 4781 XFree(text->value); 4782 4783 return result; 4784} 4785 4786static char * 4787get_icon_label(XtermWidget xw) 4788{ 4789 XTextProperty text; 4790 char *result = 0; 4791 4792 if (XGetWMIconName(TScreenOf(xw)->display, VShellWindow(xw), &text)) { 4793 result = property_to_string(xw, &text); 4794 } 4795 return result; 4796} 4797 4798static char * 4799get_window_label(XtermWidget xw) 4800{ 4801 XTextProperty text; 4802 char *result = 0; 4803 4804 if (XGetWMName(TScreenOf(xw)->display, VShellWindow(xw), &text)) { 4805 result = property_to_string(xw, &text); 4806 } 4807 return result; 4808} 4809 4810/* 4811 * Report window label (icon or title) in dtterm protocol 4812 * ESC ] code label ESC backslash 4813 */ 4814static void 4815report_win_label(XtermWidget xw, 4816 int code, 4817 char *text) 4818{ 4819 reply.a_type = ANSI_ESC; 4820 unparseputc(xw, ANSI_ESC); 4821 unparseputc(xw, ']'); 4822 unparseputc(xw, code); 4823 4824 if (text != 0) { 4825 int copy = IsTitleMode(xw, tmGetBase16); 4826 if (copy) { 4827 TRACE(("Encoding hex:%s\n", text)); 4828 text = x_encode_hex(text); 4829 } 4830 unparseputs(xw, text); 4831 if (copy) 4832 free(text); 4833 } 4834 4835 unparseputc(xw, ANSI_ESC); 4836 unparseputc(xw, '\\'); /* should be ST */ 4837 unparse_end(xw); 4838} 4839 4840/* 4841 * Window operations (from CDE dtterm description, as well as extensions). 4842 * See also "allowWindowOps" resource. 4843 */ 4844static void 4845window_ops(XtermWidget xw) 4846{ 4847 TScreen *screen = TScreenOf(xw); 4848 XWindowChanges values; 4849 XWindowAttributes win_attrs; 4850 unsigned value_mask; 4851#if OPT_MAXIMIZE 4852 unsigned root_width; 4853 unsigned root_height; 4854#endif 4855 4856 TRACE(("window_ops %d\n", param[0])); 4857 switch (param[0]) { 4858 case ewRestoreWin: /* Restore (de-iconify) window */ 4859 if (AllowWindowOps(xw, ewRestoreWin)) { 4860 TRACE(("...de-iconify window\n")); 4861 XMapWindow(screen->display, 4862 VShellWindow(xw)); 4863 } 4864 break; 4865 4866 case ewMinimizeWin: /* Minimize (iconify) window */ 4867 if (AllowWindowOps(xw, ewMinimizeWin)) { 4868 TRACE(("...iconify window\n")); 4869 XIconifyWindow(screen->display, 4870 VShellWindow(xw), 4871 DefaultScreen(screen->display)); 4872 } 4873 break; 4874 4875 case ewSetWinPosition: /* Move the window to the given position */ 4876 if (AllowWindowOps(xw, ewSetWinPosition)) { 4877 values.x = zero_if_default(1); 4878 values.y = zero_if_default(2); 4879 TRACE(("...move window to %d,%d\n", values.x, values.y)); 4880 value_mask = (CWX | CWY); 4881 XReconfigureWMWindow(screen->display, 4882 VShellWindow(xw), 4883 DefaultScreen(screen->display), 4884 value_mask, 4885 &values); 4886 } 4887 break; 4888 4889 case ewSetWinSizePixels: /* Resize the window to given size in pixels */ 4890 if (AllowWindowOps(xw, ewSetWinSizePixels)) { 4891 RequestResize(xw, zero_if_default(1), zero_if_default(2), False); 4892 } 4893 break; 4894 4895 case ewRaiseWin: /* Raise the window to the front of the stack */ 4896 if (AllowWindowOps(xw, ewRaiseWin)) { 4897 TRACE(("...raise window\n")); 4898 XRaiseWindow(screen->display, VShellWindow(xw)); 4899 } 4900 break; 4901 4902 case ewLowerWin: /* Lower the window to the bottom of the stack */ 4903 if (AllowWindowOps(xw, ewLowerWin)) { 4904 TRACE(("...lower window\n")); 4905 XLowerWindow(screen->display, VShellWindow(xw)); 4906 } 4907 break; 4908 4909 case ewRefreshWin: /* Refresh the window */ 4910 if (AllowWindowOps(xw, ewRefreshWin)) { 4911 TRACE(("...redraw window\n")); 4912 Redraw(); 4913 } 4914 break; 4915 4916 case ewSetWinSizeChars: /* Resize the text-area, in characters */ 4917 if (AllowWindowOps(xw, ewSetWinSizeChars)) { 4918 RequestResize(xw, zero_if_default(1), zero_if_default(2), True); 4919 } 4920 break; 4921 4922#if OPT_MAXIMIZE 4923 case ewMaximizeWin: /* Maximize or restore */ 4924 if (AllowWindowOps(xw, ewMaximizeWin)) { 4925 RequestMaximize(xw, zero_if_default(1)); 4926 } 4927 break; 4928 case ewFullscreenWin: /* Fullscreen or restore */ 4929 if (AllowWindowOps(xw, ewFullscreenWin)) { 4930 FullScreen(xw, zero_if_default(1)); 4931 } 4932 break; 4933#endif 4934 4935 case ewGetWinState: /* Report the window's state */ 4936 if (AllowWindowOps(xw, ewGetWinState)) { 4937 TRACE(("...get window attributes\n")); 4938 XGetWindowAttributes(screen->display, 4939 VWindow(screen), 4940 &win_attrs); 4941 reply.a_type = ANSI_CSI; 4942 reply.a_pintro = 0; 4943 reply.a_nparam = 1; 4944 reply.a_param[0] = (ParmType) ((win_attrs.map_state == IsViewable) 4945 ? 1 4946 : 2); 4947 reply.a_inters = 0; 4948 reply.a_final = 't'; 4949 unparseseq(xw, &reply); 4950 } 4951 break; 4952 4953 case ewGetWinPosition: /* Report the window's position */ 4954 if (AllowWindowOps(xw, ewGetWinPosition)) { 4955 TRACE(("...get window position\n")); 4956 XGetWindowAttributes(screen->display, 4957 WMFrameWindow(xw), 4958 &win_attrs); 4959 reply.a_type = ANSI_CSI; 4960 reply.a_pintro = 0; 4961 reply.a_nparam = 3; 4962 reply.a_param[0] = 3; 4963 reply.a_param[1] = (ParmType) win_attrs.x; 4964 reply.a_param[2] = (ParmType) win_attrs.y; 4965 reply.a_inters = 0; 4966 reply.a_final = 't'; 4967 unparseseq(xw, &reply); 4968 } 4969 break; 4970 4971 case ewGetWinSizePixels: /* Report the window's size in pixels */ 4972 if (AllowWindowOps(xw, ewGetWinSizePixels)) { 4973 TRACE(("...get window size in pixels\n")); 4974 XGetWindowAttributes(screen->display, 4975 VWindow(screen), 4976 &win_attrs); 4977 reply.a_type = ANSI_CSI; 4978 reply.a_pintro = 0; 4979 reply.a_nparam = 3; 4980 reply.a_param[0] = 4; 4981 /*FIXME: find if dtterm uses 4982 * win_attrs.height or Height 4983 * win_attrs.width or Width 4984 */ 4985 reply.a_param[1] = (ParmType) Height(screen); 4986 reply.a_param[2] = (ParmType) Width(screen); 4987 reply.a_inters = 0; 4988 reply.a_final = 't'; 4989 unparseseq(xw, &reply); 4990 } 4991 break; 4992 4993 case ewGetWinSizeChars: /* Report the text's size in characters */ 4994 if (AllowWindowOps(xw, ewGetWinSizeChars)) { 4995 TRACE(("...get window size in characters\n")); 4996 reply.a_type = ANSI_CSI; 4997 reply.a_pintro = 0; 4998 reply.a_nparam = 3; 4999 reply.a_param[0] = 8; 5000 reply.a_param[1] = (ParmType) MaxRows(screen); 5001 reply.a_param[2] = (ParmType) MaxCols(screen); 5002 reply.a_inters = 0; 5003 reply.a_final = 't'; 5004 unparseseq(xw, &reply); 5005 } 5006 break; 5007 5008#if OPT_MAXIMIZE 5009 case ewGetScreenSizeChars: /* Report the screen's size, in characters */ 5010 if (AllowWindowOps(xw, ewGetScreenSizeChars)) { 5011 TRACE(("...get screen size in characters\n")); 5012 if (!QueryMaximize(xw, &root_height, &root_width)) { 5013 root_height = 0; 5014 root_width = 0; 5015 } 5016 reply.a_type = ANSI_CSI; 5017 reply.a_pintro = 0; 5018 reply.a_nparam = 3; 5019 reply.a_param[0] = 9; 5020 reply.a_param[1] = (ParmType) (root_height 5021 / (unsigned) FontHeight(screen)); 5022 reply.a_param[2] = (ParmType) (root_width 5023 / (unsigned) FontWidth(screen)); 5024 reply.a_inters = 0; 5025 reply.a_final = 't'; 5026 unparseseq(xw, &reply); 5027 } 5028 break; 5029#endif 5030 5031 case ewGetIconTitle: /* Report the icon's label */ 5032 if (AllowWindowOps(xw, ewGetIconTitle)) { 5033 TRACE(("...get icon's label\n")); 5034 report_win_label(xw, 'L', get_icon_label(xw)); 5035 } 5036 break; 5037 5038 case ewGetWinTitle: /* Report the window's title */ 5039 if (AllowWindowOps(xw, ewGetWinTitle)) { 5040 TRACE(("...get window's label\n")); 5041 report_win_label(xw, 'l', get_window_label(xw)); 5042 } 5043 break; 5044 5045 case ewPushTitle: /* save the window's title(s) on stack */ 5046 if (AllowWindowOps(xw, ewPushTitle)) { 5047 SaveTitle *last = screen->save_title; 5048 SaveTitle *item = TypeCalloc(SaveTitle); 5049 5050 TRACE(("...push title onto stack\n")); 5051 if (item != 0) { 5052 switch (zero_if_default(1)) { 5053 case 0: 5054 item->iconName = get_icon_label(xw); 5055 item->windowName = get_window_label(xw); 5056 break; 5057 case 1: 5058 item->iconName = get_icon_label(xw); 5059 break; 5060 case 2: 5061 item->windowName = get_window_label(xw); 5062 break; 5063 } 5064 item->next = last; 5065 if (item->iconName == 0) { 5066 item->iconName = ((last == 0) 5067 ? get_icon_label(xw) 5068 : x_strdup(last->iconName)); 5069 } 5070 if (item->windowName == 0) { 5071 item->windowName = ((last == 0) 5072 ? get_window_label(xw) 5073 : x_strdup(last->windowName)); 5074 } 5075 screen->save_title = item; 5076 } 5077 } 5078 break; 5079 5080 case ewPopTitle: /* restore the window's title(s) from stack */ 5081 if (AllowWindowOps(xw, ewPopTitle)) { 5082 SaveTitle *item = screen->save_title; 5083 5084 TRACE(("...pop title off stack\n")); 5085 if (item != 0) { 5086 switch (zero_if_default(1)) { 5087 case 0: 5088 ChangeIconName(xw, item->iconName); 5089 ChangeTitle(xw, item->windowName); 5090 break; 5091 case 1: 5092 ChangeIconName(xw, item->iconName); 5093 break; 5094 case 2: 5095 ChangeTitle(xw, item->windowName); 5096 break; 5097 } 5098 screen->save_title = item->next; 5099 free(item->iconName); 5100 free(item->windowName); 5101 free(item); 5102 } 5103 } 5104 break; 5105 5106 default: /* DECSLPP (24, 25, 36, 48, 72, 144) */ 5107 if (AllowWindowOps(xw, ewSetWinLines)) { 5108 if (param[0] >= 24) 5109 RequestResize(xw, param[0], -1, True); 5110 } 5111 break; 5112 } 5113} 5114 5115/* 5116 * set a bit in a word given a pointer to the word and a mask. 5117 */ 5118static void 5119bitset(unsigned *p, unsigned mask) 5120{ 5121 *p |= mask; 5122} 5123 5124/* 5125 * clear a bit in a word given a pointer to the word and a mask. 5126 */ 5127static void 5128bitclr(unsigned *p, unsigned mask) 5129{ 5130 *p &= ~mask; 5131} 5132 5133/* 5134 * Copy bits from one word to another, given a mask 5135 */ 5136static void 5137bitcpy(unsigned *p, unsigned q, unsigned mask) 5138{ 5139 bitclr(p, mask); 5140 bitset(p, q & mask); 5141} 5142 5143void 5144unparseputc1(XtermWidget xw, int c) 5145{ 5146 if (c >= 0x80 && c <= 0x9F) { 5147 if (!TScreenOf(xw)->control_eight_bits) { 5148 unparseputc(xw, A2E(ANSI_ESC)); 5149 c = A2E(c - 0x40); 5150 } 5151 } 5152 unparseputc(xw, c); 5153} 5154 5155void 5156unparseseq(XtermWidget xw, ANSI * ap) 5157{ 5158 int c; 5159 int i; 5160 int inters; 5161 5162 unparseputc1(xw, c = ap->a_type); 5163 if (c == ANSI_ESC 5164 || c == ANSI_DCS 5165 || c == ANSI_CSI 5166 || c == ANSI_OSC 5167 || c == ANSI_PM 5168 || c == ANSI_APC 5169 || c == ANSI_SS3) { 5170 if (ap->a_pintro != 0) 5171 unparseputc(xw, ap->a_pintro); 5172 for (i = 0; i < ap->a_nparam; ++i) { 5173 if (i != 0) 5174 unparseputc(xw, ';'); 5175 unparseputn(xw, (unsigned int) ap->a_param[i]); 5176 } 5177 if ((inters = ap->a_inters) != 0) { 5178 for (i = 3; i >= 0; --i) { 5179 c = CharOf(inters >> (8 * i)); 5180 if (c != 0) 5181 unparseputc(xw, c); 5182 } 5183 } 5184 unparseputc(xw, (char) ap->a_final); 5185 } 5186 unparse_end(xw); 5187} 5188 5189void 5190unparseputn(XtermWidget xw, unsigned int n) 5191{ 5192 unsigned int q; 5193 5194 q = n / 10; 5195 if (q != 0) 5196 unparseputn(xw, q); 5197 unparseputc(xw, (char) ('0' + (n % 10))); 5198} 5199 5200void 5201unparseputs(XtermWidget xw, const char *s) 5202{ 5203 if (s != 0) { 5204 while (*s) 5205 unparseputc(xw, *s++); 5206 } 5207} 5208 5209void 5210unparseputc(XtermWidget xw, int c) 5211{ 5212 TScreen *screen = TScreenOf(xw); 5213 IChar *buf = screen->unparse_bfr; 5214 unsigned len; 5215 5216 if ((screen->unparse_len + 2) >= sizeof(screen->unparse_bfr)) 5217 unparse_end(xw); 5218 5219 len = screen->unparse_len; 5220 5221#if OPT_TCAP_QUERY 5222 /* 5223 * If we're returning a termcap string, it has to be translated since 5224 * a DCS must not contain any characters except for the normal 7-bit 5225 * printable ASCII (counting tab, carriage return, etc). For now, 5226 * just use hexadecimal for the whole thing. 5227 */ 5228 if (screen->tc_query_code >= 0) { 5229 char tmp[3]; 5230 sprintf(tmp, "%02X", c & 0xFF); 5231 buf[len++] = CharOf(tmp[0]); 5232 buf[len++] = CharOf(tmp[1]); 5233 } else 5234#endif 5235 if ((buf[len++] = (IChar) c) == '\r' && (xw->flags & LINEFEED)) { 5236 buf[len++] = '\n'; 5237 } 5238 5239 screen->unparse_len = len; 5240 5241 /* If send/receive mode is reset, we echo characters locally */ 5242 if ((xw->keyboard.flags & MODE_SRM) == 0) { 5243 (void) doparsing(xw, (unsigned) c, &myState); 5244 } 5245} 5246 5247void 5248unparse_end(XtermWidget xw) 5249{ 5250 TScreen *screen = TScreenOf(xw); 5251 5252 if (screen->unparse_len) { 5253#ifdef VMS 5254 tt_write(screen->unparse_bfr, screen->unparse_len); 5255#else /* VMS */ 5256 writePtyData(screen->respond, screen->unparse_bfr, screen->unparse_len); 5257#endif /* VMS */ 5258 screen->unparse_len = 0; 5259 } 5260} 5261 5262void 5263ToggleAlternate(XtermWidget xw) 5264{ 5265 if (TScreenOf(xw)->whichBuf) 5266 FromAlternate(xw); 5267 else 5268 ToAlternate(xw); 5269} 5270 5271static void 5272ToAlternate(XtermWidget xw) 5273{ 5274 TScreen *screen = TScreenOf(xw); 5275 5276 if (screen->whichBuf == 0) { 5277 TRACE(("ToAlternate\n")); 5278 if (!screen->editBuf_index[1]) 5279 screen->editBuf_index[1] = allocScrnBuf(xw, 5280 (unsigned) MaxRows(screen), 5281 (unsigned) MaxCols(screen), 5282 &screen->editBuf_data[1]); 5283 SwitchBufs(xw, 1); 5284 screen->whichBuf = 1; 5285#if OPT_SAVE_LINES 5286 screen->visbuf = screen->editBuf_index[screen->whichBuf]; 5287#endif 5288 update_altscreen(); 5289 } 5290} 5291 5292static void 5293FromAlternate(XtermWidget xw) 5294{ 5295 TScreen *screen = TScreenOf(xw); 5296 5297 if (screen->whichBuf != 0) { 5298 TRACE(("FromAlternate\n")); 5299 if (screen->scroll_amt) 5300 FlushScroll(xw); 5301 screen->whichBuf = 0; 5302 SwitchBufs(xw, 0); 5303#if OPT_SAVE_LINES 5304 screen->visbuf = screen->editBuf_index[screen->whichBuf]; 5305#endif 5306 update_altscreen(); 5307 } 5308} 5309 5310static void 5311SwitchBufs(XtermWidget xw, int toBuf) 5312{ 5313 TScreen *screen = TScreenOf(xw); 5314 int rows, top; 5315 5316 if (screen->cursor_state) 5317 HideCursor(); 5318 5319 rows = MaxRows(screen); 5320 SwitchBufPtrs(screen, toBuf); 5321 5322 if ((top = INX2ROW(screen, 0)) < rows) { 5323 if (screen->scroll_amt) { 5324 FlushScroll(xw); 5325 } 5326 XClearArea(screen->display, 5327 VWindow(screen), 5328 (int) OriginX(screen), 5329 (int) top * FontHeight(screen) + screen->border, 5330 (unsigned) Width(screen), 5331 (unsigned) ((rows - top) * FontHeight(screen)), 5332 False); 5333 } 5334 ScrnUpdate(xw, 0, 0, rows, MaxCols(screen), False); 5335} 5336 5337Bool 5338CheckBufPtrs(TScreen * screen) 5339{ 5340 return (screen->visbuf != 0 5341#if OPT_SAVE_LINES 5342 && screen->editBuf_index[0] != 0 5343#endif 5344 && screen->editBuf_index[1] != 0); 5345} 5346 5347/* 5348 * Swap buffer line pointers between alternate and regular screens. 5349 */ 5350void 5351SwitchBufPtrs(TScreen * screen, int toBuf GCC_UNUSED) 5352{ 5353 if (CheckBufPtrs(screen)) { 5354#if OPT_SAVE_LINES 5355 screen->visbuf = screen->editBuf_index[toBuf]; 5356#else 5357 size_t len = ScrnPointers(screen, (size_t) MaxRows(screen)); 5358 5359 memcpy(screen->save_ptr, screen->visbuf, len); 5360 memcpy(screen->visbuf, screen->editBuf_index[1], len); 5361 memcpy(screen->editBuf_index[1], screen->save_ptr, len); 5362#endif 5363 } 5364} 5365 5366void 5367VTRun(XtermWidget xw) 5368{ 5369 TScreen *screen = TScreenOf(xw); 5370 5371 TRACE(("VTRun ...\n")); 5372 5373 if (!screen->Vshow) { 5374 set_vt_visibility(True); 5375 } 5376 update_vttekmode(); 5377 update_vtshow(); 5378 update_tekshow(); 5379 set_vthide_sensitivity(); 5380 5381 ScrnAllocBuf(xw); 5382 5383 screen->cursor_state = OFF; 5384 screen->cursor_set = ON; 5385#if OPT_BLINK_CURS 5386 if (DoStartBlinking(screen)) 5387 StartBlinking(screen); 5388#endif 5389 5390#if OPT_TEK4014 5391 if (Tpushb > Tpushback) { 5392 fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback)); 5393 Tpushb = Tpushback; 5394 } 5395#endif 5396 screen->is_running = True; 5397#if OPT_MAXIMIZE 5398 if (resource.fullscreen == esTrue || resource.fullscreen == esAlways) 5399 FullScreen(term, True); 5400#endif 5401 if (!setjmp(VTend)) 5402 VTparse(xw); 5403 StopBlinking(screen); 5404 HideCursor(); 5405 screen->cursor_set = OFF; 5406 TRACE(("... VTRun\n")); 5407} 5408 5409/*ARGSUSED*/ 5410static void 5411VTExpose(Widget w GCC_UNUSED, 5412 XEvent * event, 5413 Region region GCC_UNUSED) 5414{ 5415#ifdef DEBUG 5416 if (debug) 5417 fputs("Expose\n", stderr); 5418#endif /* DEBUG */ 5419 if (event->type == Expose) 5420 HandleExposure(term, event); 5421} 5422 5423static void 5424VTGraphicsOrNoExpose(XEvent * event) 5425{ 5426 TScreen *screen = TScreenOf(term); 5427 if (screen->incopy <= 0) { 5428 screen->incopy = 1; 5429 if (screen->scrolls > 0) 5430 screen->scrolls--; 5431 } 5432 if (event->type == GraphicsExpose) 5433 if (HandleExposure(term, event)) 5434 screen->cursor_state = OFF; 5435 if ((event->type == NoExpose) 5436 || ((XGraphicsExposeEvent *) event)->count == 0) { 5437 if (screen->incopy <= 0 && screen->scrolls > 0) 5438 screen->scrolls--; 5439 if (screen->scrolls) 5440 screen->incopy = -1; 5441 else 5442 screen->incopy = 0; 5443 } 5444} 5445 5446/*ARGSUSED*/ 5447static void 5448VTNonMaskableEvent(Widget w GCC_UNUSED, 5449 XtPointer closure GCC_UNUSED, 5450 XEvent * event, 5451 Boolean * cont GCC_UNUSED) 5452{ 5453 switch (event->type) { 5454 case GraphicsExpose: 5455 case NoExpose: 5456 VTGraphicsOrNoExpose(event); 5457 break; 5458 } 5459} 5460 5461static void 5462VTResize(Widget w) 5463{ 5464 if (XtIsRealized(w)) { 5465 XtermWidget xw = (XtermWidget) w; 5466 ScreenResize(xw, xw->core.width, xw->core.height, &xw->flags); 5467 } 5468} 5469 5470#define okDimension(src,dst) ((src <= 32767) \ 5471 && ((dst = (Dimension) src) == src)) 5472 5473static void 5474RequestResize(XtermWidget xw, int rows, int cols, Bool text) 5475{ 5476 TScreen *screen = TScreenOf(xw); 5477 unsigned long value; 5478 Dimension replyWidth, replyHeight; 5479 Dimension askedWidth, askedHeight; 5480 XtGeometryResult status; 5481 XWindowAttributes attrs; 5482 5483 TRACE(("RequestResize(rows=%d, cols=%d, text=%d)\n", rows, cols, text)); 5484 5485 if ((int) (askedWidth = (Dimension) cols) < cols 5486 || (int) (askedHeight = (Dimension) rows) < rows) 5487 return; 5488 5489 if (askedHeight == 0 5490 || askedWidth == 0 5491 || xw->misc.limit_resize > 0) { 5492 XGetWindowAttributes(XtDisplay(xw), 5493 RootWindowOfScreen(XtScreen(xw)), &attrs); 5494 } 5495 5496 if (text) { 5497 if ((value = (unsigned long) rows) != 0) { 5498 if (rows < 0) 5499 value = (unsigned long) MaxRows(screen); 5500 value *= (unsigned long) FontHeight(screen); 5501 value += (unsigned long) (2 * screen->border); 5502 if (!okDimension(value, askedHeight)) 5503 return; 5504 } 5505 5506 if ((value = (unsigned long) cols) != 0) { 5507 if (cols < 0) 5508 value = (unsigned long) MaxCols(screen); 5509 value *= (unsigned long) FontWidth(screen); 5510 value += (unsigned long) ((2 * screen->border) 5511 + ScrollbarWidth(screen)); 5512 if (!okDimension(value, askedWidth)) 5513 return; 5514 } 5515 5516 } else { 5517 if (rows < 0) 5518 askedHeight = FullHeight(screen); 5519 if (cols < 0) 5520 askedWidth = FullWidth(screen); 5521 } 5522 5523 if (rows == 0) 5524 askedHeight = (Dimension) attrs.height; 5525 if (cols == 0) 5526 askedWidth = (Dimension) attrs.width; 5527 5528 if (xw->misc.limit_resize > 0) { 5529 Dimension high = (Dimension) (xw->misc.limit_resize * attrs.height); 5530 Dimension wide = (Dimension) (xw->misc.limit_resize * attrs.width); 5531 if ((int) high < attrs.height) 5532 high = (Dimension) attrs.height; 5533 if (askedHeight > high) 5534 askedHeight = high; 5535 if ((int) wide < attrs.width) 5536 wide = (Dimension) attrs.width; 5537 if (askedWidth > wide) 5538 askedWidth = wide; 5539 } 5540#ifndef nothack 5541 getXtermSizeHints(xw); 5542#endif 5543 5544 TRACE(("...requesting resize %dx%d\n", askedHeight, askedWidth)); 5545 status = REQ_RESIZE((Widget) xw, 5546 askedWidth, askedHeight, 5547 &replyWidth, &replyHeight); 5548 5549 if (status == XtGeometryYes || 5550 status == XtGeometryDone) { 5551 ScreenResize(xw, replyWidth, replyHeight, &xw->flags); 5552 } 5553#ifndef nothack 5554 /* 5555 * XtMakeResizeRequest() has the undesirable side-effect of clearing 5556 * the window manager's hints, even on a failed request. This would 5557 * presumably be fixed if the shell did its own work. 5558 */ 5559 if (xw->hints.flags 5560 && replyHeight 5561 && replyWidth) { 5562 xw->hints.height = replyHeight; 5563 xw->hints.width = replyWidth; 5564 5565 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 5566 TRACE_HINTS(&xw->hints); 5567 XSetWMNormalHints(screen->display, VShellWindow(xw), &xw->hints); 5568 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 5569 TRACE_WM_HINTS(xw); 5570 } 5571#endif 5572 5573 XSync(screen->display, False); /* synchronize */ 5574 if (XtAppPending(app_con)) 5575 xevents(); 5576 5577 TRACE(("...RequestResize done\n")); 5578} 5579 5580static String xterm_trans = 5581"<ClientMessage>WM_PROTOCOLS: DeleteWindow()\n\ 5582 <MappingNotify>: KeyboardMapping()\n"; 5583 5584int 5585VTInit(XtermWidget xw) 5586{ 5587 Widget vtparent = SHELL_OF(xw); 5588 5589 TRACE(("VTInit {{\n")); 5590 5591 XtRealizeWidget(vtparent); 5592 XtOverrideTranslations(vtparent, XtParseTranslationTable(xterm_trans)); 5593 (void) XSetWMProtocols(XtDisplay(vtparent), XtWindow(vtparent), 5594 &wm_delete_window, 1); 5595 TRACE_TRANS("shell", vtparent); 5596 TRACE_TRANS("vt100", (Widget) (xw)); 5597 5598 ScrnAllocBuf(xw); 5599 5600 TRACE(("...}} VTInit\n")); 5601 return (1); 5602} 5603 5604static void 5605VTClassInit(void) 5606{ 5607 XtAddConverter(XtRString, XtRGravity, XmuCvtStringToGravity, 5608 (XtConvertArgList) NULL, (Cardinal) 0); 5609} 5610 5611#if OPT_COLOR_RES 5612/* 5613 * Override the use of XtDefaultForeground/XtDefaultBackground to make some 5614 * colors, such as cursor color, use the actual foreground/background value 5615 * if there is no explicit resource value used. 5616 */ 5617static Pixel 5618fill_Tres(XtermWidget target, XtermWidget source, int offset) 5619{ 5620 char *name; 5621 ScrnColors temp; 5622 5623 TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset]; 5624 TScreenOf(target)->Tcolors[offset].mode = False; 5625 5626 if ((name = x_strtrim(TScreenOf(target)->Tcolors[offset].resource)) != 0) 5627 TScreenOf(target)->Tcolors[offset].resource = name; 5628 5629 if (name == 0) { 5630 TScreenOf(target)->Tcolors[offset].value = target->dft_foreground; 5631 } else if (isDefaultForeground(name)) { 5632 TScreenOf(target)->Tcolors[offset].value = 5633 ((offset == TEXT_FG || offset == TEXT_BG) 5634 ? target->dft_foreground 5635 : TScreenOf(target)->Tcolors[TEXT_FG].value); 5636 } else if (isDefaultBackground(name)) { 5637 TScreenOf(target)->Tcolors[offset].value = 5638 ((offset == TEXT_FG || offset == TEXT_BG) 5639 ? target->dft_background 5640 : TScreenOf(target)->Tcolors[TEXT_BG].value); 5641 } else { 5642 memset(&temp, 0, sizeof(temp)); 5643 if (AllocateTermColor(target, &temp, offset, name, True)) { 5644 if (COLOR_DEFINED(&(temp), offset)) 5645 free(temp.names[offset]); 5646 TScreenOf(target)->Tcolors[offset].value = temp.colors[offset]; 5647 } 5648 } 5649 return TScreenOf(target)->Tcolors[offset].value; 5650} 5651#else 5652#define fill_Tres(target, source, offset) \ 5653 TScreenOf(target)->Tcolors[offset] = TScreenOf(source)->Tcolors[offset] 5654#endif 5655 5656#if OPT_WIDE_CHARS 5657static void 5658VTInitialize_locale(XtermWidget xw) 5659{ 5660 TScreen *screen = TScreenOf(xw); 5661 Bool is_utf8 = xtermEnvUTF8(); 5662 5663 TRACE(("VTInitialize_locale\n")); 5664 TRACE(("... request screen.utf8_mode = %d\n", screen->utf8_mode)); 5665 5666 if (screen->utf8_mode < 0) 5667 screen->utf8_mode = uFalse; 5668 5669 if (screen->utf8_mode > 3) 5670 screen->utf8_mode = uDefault; 5671 5672 screen->latin9_mode = 0; 5673 screen->unicode_font = 0; 5674#if OPT_LUIT_PROG 5675 xw->misc.callfilter = 0; 5676 xw->misc.use_encoding = 0; 5677 5678 TRACE(("... setup for luit:\n")); 5679 TRACE(("... request misc.locale_str = \"%s\"\n", xw->misc.locale_str)); 5680 5681 if (screen->utf8_mode == uFalse) { 5682 TRACE(("... command-line +u8 overrides\n")); 5683 } else 5684#if OPT_MINI_LUIT 5685 if (x_strcasecmp(xw->misc.locale_str, "CHECKFONT") == 0) { 5686 int fl = (xw->misc.default_font.f_n 5687 ? (int) strlen(xw->misc.default_font.f_n) 5688 : 0); 5689 if (fl > 11 5690 && x_strcasecmp(xw->misc.default_font.f_n + fl - 11, 5691 "-ISO10646-1") == 0) { 5692 screen->unicode_font = 1; 5693 /* unicode font, use True */ 5694#ifdef HAVE_LANGINFO_CODESET 5695 if (!strcmp(xtermEnvEncoding(), "ANSI_X3.4-1968") 5696 || !strcmp(xtermEnvEncoding(), "ISO-8859-1")) { 5697 if (screen->utf8_mode == uDefault) 5698 screen->utf8_mode = uFalse; 5699 } else if (!strcmp(xtermEnvEncoding(), "ISO-8859-15")) { 5700 if (screen->utf8_mode == uDefault) 5701 screen->utf8_mode = uFalse; 5702 screen->latin9_mode = 1; 5703 } else { 5704 xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1); 5705 screen->utf8_mode = uAlways; 5706 } 5707#else 5708 xw->misc.callfilter = is_utf8 ? 0 : 1; 5709 screen->utf8_mode = uAlways; 5710#endif 5711 } else { 5712 /* other encoding, use False */ 5713 if (screen->utf8_mode == uDefault) { 5714 screen->utf8_mode = is_utf8 ? uAlways : uFalse; 5715 } 5716 } 5717 } else 5718#endif /* OPT_MINI_LUIT */ 5719 if (x_strcasecmp(xw->misc.locale_str, "TRUE") == 0 || 5720 x_strcasecmp(xw->misc.locale_str, "ON") == 0 || 5721 x_strcasecmp(xw->misc.locale_str, "YES") == 0 || 5722 x_strcasecmp(xw->misc.locale_str, "AUTO") == 0 || 5723 strcmp(xw->misc.locale_str, "1") == 0) { 5724 /* when true ... fully obeying LC_CTYPE locale */ 5725 xw->misc.callfilter = (Boolean) (is_utf8 ? 0 : 1); 5726 screen->utf8_mode = uAlways; 5727 } else if (x_strcasecmp(xw->misc.locale_str, "FALSE") == 0 || 5728 x_strcasecmp(xw->misc.locale_str, "OFF") == 0 || 5729 x_strcasecmp(xw->misc.locale_str, "NO") == 0 || 5730 strcmp(xw->misc.locale_str, "0") == 0) { 5731 /* when false ... original value of utf8_mode is effective */ 5732 if (screen->utf8_mode == uDefault) { 5733 screen->utf8_mode = is_utf8 ? uAlways : uFalse; 5734 } 5735 } else if (x_strcasecmp(xw->misc.locale_str, "MEDIUM") == 0 || 5736 x_strcasecmp(xw->misc.locale_str, "SEMIAUTO") == 0) { 5737 /* when medium ... obeying locale only for UTF-8 and Asian */ 5738 if (is_utf8) { 5739 screen->utf8_mode = uAlways; 5740 } else if ( 5741#ifdef MB_CUR_MAX 5742 MB_CUR_MAX > 1 || 5743#else 5744 !strncmp(xtermEnvLocale(), "ja", (size_t) 2) || 5745 !strncmp(xtermEnvLocale(), "ko", (size_t) 2) || 5746 !strncmp(xtermEnvLocale(), "zh", (size_t) 2) || 5747#endif 5748 !strncmp(xtermEnvLocale(), "th", (size_t) 2) || 5749 !strncmp(xtermEnvLocale(), "vi", (size_t) 2)) { 5750 xw->misc.callfilter = 1; 5751 screen->utf8_mode = uAlways; 5752 } else { 5753 screen->utf8_mode = uFalse; 5754 } 5755 } else if (x_strcasecmp(xw->misc.locale_str, "UTF-8") == 0 || 5756 x_strcasecmp(xw->misc.locale_str, "UTF8") == 0) { 5757 /* when UTF-8 ... UTF-8 mode */ 5758 screen->utf8_mode = uAlways; 5759 } else { 5760 /* other words are regarded as encoding name passed to luit */ 5761 xw->misc.callfilter = 1; 5762 screen->utf8_mode = uAlways; 5763 xw->misc.use_encoding = 1; 5764 } 5765 TRACE(("... updated misc.callfilter = %s\n", BtoS(xw->misc.callfilter))); 5766 TRACE(("... updated misc.use_encoding = %s\n", BtoS(xw->misc.use_encoding))); 5767#else 5768 if (screen->utf8_mode == uDefault) { 5769 screen->utf8_mode = is_utf8 ? uAlways : uFalse; 5770 } 5771#endif /* OPT_LUIT_PROG */ 5772 5773 screen->utf8_inparse = (Boolean) (screen->utf8_mode != uFalse); 5774 5775 TRACE(("... updated screen.utf8_mode = %d\n", screen->utf8_mode)); 5776 TRACE(("...VTInitialize_locale done\n")); 5777} 5778#endif 5779 5780static void 5781ParseOnClicks(XtermWidget wnew, XtermWidget wreq, Cardinal item) 5782{ 5783 /* *INDENT-OFF* */ 5784 static struct { 5785 const char * name; 5786 SelectUnit code; 5787 } table[] = { 5788 { "char", Select_CHAR }, 5789 { "word", Select_WORD }, 5790 { "line", Select_LINE }, 5791 { "group", Select_GROUP }, 5792 { "page", Select_PAGE }, 5793 { "all", Select_ALL }, 5794#if OPT_SELECT_REGEX 5795 { "regex", Select_REGEX }, 5796#endif 5797 }; 5798 /* *INDENT-ON* */ 5799 5800 String res = TScreenOf(wreq)->onClick[item]; 5801 String next = x_skip_nonblanks(res); 5802 Cardinal n; 5803 5804 TScreenOf(wnew)->selectMap[item] = NSELECTUNITS; 5805 for (n = 0; n < XtNumber(table); ++n) { 5806 if (!x_strncasecmp(table[n].name, res, (unsigned) (next - res))) { 5807 TScreenOf(wnew)->selectMap[item] = table[n].code; 5808#if OPT_SELECT_REGEX 5809 if (table[n].code == Select_REGEX) { 5810 TScreenOf(wnew)->selectExpr[item] = x_strtrim(next); 5811 TRACE(("Parsed regex \"%s\"\n", TScreenOf(wnew)->selectExpr[item])); 5812 } 5813#endif 5814 break; 5815 } 5816 } 5817} 5818 5819/* 5820 * Parse a comma-separated list, returning a string which the caller must 5821 * free, and updating the source pointer. 5822 */ 5823static char * 5824ParseList(const char **source) 5825{ 5826 const char *base = *source; 5827 const char *next; 5828 size_t size; 5829 char *value = 0; 5830 char *result; 5831 5832 /* ignore empty values */ 5833 while (*base == ',') 5834 ++base; 5835 if (*base != '\0') { 5836 next = base; 5837 while (*next != '\0' && *next != ',') 5838 ++next; 5839 size = (size_t) (1 + next - base); 5840 value = malloc(size); 5841 if (value != 0) { 5842 memcpy(value, base, size); 5843 value[size - 1] = '\0'; 5844 } 5845 *source = next; 5846 } else { 5847 *source = base; 5848 } 5849 result = x_strtrim(value); 5850 free(value); 5851 return result; 5852} 5853 5854static void 5855set_flags_from_list(char *target, 5856 const char *source, 5857 FlagList * list, 5858 Cardinal limit) 5859{ 5860 Cardinal n; 5861 int value = -1; 5862 5863 while (*source != '\0') { 5864 char *next = ParseList(&source); 5865 Boolean found = False; 5866 5867 if (next == 0) 5868 break; 5869 if (isdigit(CharOf(*next))) { 5870 char *temp; 5871 5872 value = (int) strtol(next, &temp, 0); 5873 if (!IsEmpty(temp)) { 5874 fprintf(stderr, "Expected a number: %s\n", next); 5875 } else { 5876 for (n = 0; n < limit; ++n) { 5877 if (list[n].code == value) { 5878 target[value] = 1; 5879 found = True; 5880 break; 5881 } 5882 } 5883 } 5884 } else { 5885 for (n = 0; n < limit; ++n) { 5886 if (!x_strcasecmp(next, list[n].name)) { 5887 value = list[n].code; 5888 target[value] = 1; 5889 found = True; 5890 break; 5891 } 5892 } 5893 } 5894 if (!found) { 5895 fprintf(stderr, "Unrecognized keyword: %s\n", next); 5896 } else { 5897 TRACE(("...found %s (%d)\n", next, value)); 5898 } 5899 free(next); 5900 } 5901} 5902 5903/* ARGSUSED */ 5904static void 5905VTInitialize(Widget wrequest, 5906 Widget new_arg, 5907 ArgList args GCC_UNUSED, 5908 Cardinal *num_args GCC_UNUSED) 5909{ 5910#define Kolor(name) TScreenOf(wnew)->name.resource 5911#define TxtFg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_FG]), Kolor(name)) 5912#define TxtBg(name) !x_strcasecmp(Kolor(Tcolors[TEXT_BG]), Kolor(name)) 5913#define DftFg(name) isDefaultForeground(Kolor(name)) 5914#define DftBg(name) isDefaultBackground(Kolor(name)) 5915 5916#define DATA(name) { #name, ec##name } 5917 static FlagList tblColorOps[] = 5918 { 5919 DATA(SetColor) 5920 ,DATA(GetColor) 5921 ,DATA(GetAnsiColor) 5922 }; 5923#undef DATA 5924 5925#define DATA(name) { #name, ef##name } 5926 static FlagList tblFontOps[] = 5927 { 5928 DATA(SetFont) 5929 ,DATA(GetFont) 5930 }; 5931#undef DATA 5932 5933#define DATA(name) { #name, et##name } 5934 static FlagList tblTcapOps[] = 5935 { 5936 DATA(SetTcap) 5937 ,DATA(GetTcap) 5938 }; 5939#undef DATA 5940 5941#define DATA(name) { #name, ew##name } 5942 static FlagList tblWindowOps[] = 5943 { 5944 DATA(RestoreWin) 5945 ,DATA(MinimizeWin) 5946 ,DATA(SetWinPosition) 5947 ,DATA(SetWinSizePixels) 5948 ,DATA(RaiseWin) 5949 ,DATA(LowerWin) 5950 ,DATA(RefreshWin) 5951 ,DATA(SetWinSizeChars) 5952#if OPT_MAXIMIZE 5953 ,DATA(MaximizeWin) 5954 ,DATA(FullscreenWin) 5955#endif 5956 ,DATA(GetWinState) 5957 ,DATA(GetWinPosition) 5958 ,DATA(GetWinSizePixels) 5959 ,DATA(GetWinSizeChars) 5960#if OPT_MAXIMIZE 5961 ,DATA(GetScreenSizeChars) 5962#endif 5963 ,DATA(GetIconTitle) 5964 ,DATA(GetWinTitle) 5965 ,DATA(PushTitle) 5966 ,DATA(PopTitle) 5967 ,DATA(SetWinLines) 5968 ,DATA(SetXprop) 5969 ,DATA(GetSelection) 5970 ,DATA(SetSelection) 5971 }; 5972#undef DATA 5973 5974#if OPT_RENDERFONT 5975#define DATA(name) { #name, er##name } 5976 static FlagList tblRenderFont[] = 5977 { 5978 DATA(Default) 5979 }; 5980#undef DATA 5981#endif 5982 5983 XtermWidget request = (XtermWidget) wrequest; 5984 XtermWidget wnew = (XtermWidget) new_arg; 5985 Widget my_parent = SHELL_OF(wnew); 5986 int i; 5987 const char *s; 5988 5989#if OPT_ISO_COLORS 5990 Bool color_ok; 5991#endif 5992 5993#if OPT_COLOR_RES2 5994 static XtResource fake_resources[] = 5995 { 5996#if OPT_256_COLORS 5997# include <256colres.h> 5998#elif OPT_88_COLORS 5999# include <88colres.h> 6000#endif 6001 }; 6002#endif /* OPT_COLOR_RES2 */ 6003 6004 TRACE(("VTInitialize wnew %p, %d / %d resources\n", 6005 (void *) wnew, XtNumber(xterm_resources), MAXRESOURCES)); 6006 assert(XtNumber(xterm_resources) < MAXRESOURCES); 6007 6008 /* Zero out the entire "screen" component of "wnew" widget, then do 6009 * field-by-field assignment of "screen" fields that are named in the 6010 * resource list. 6011 */ 6012 memset(TScreenOf(wnew), 0, sizeof(wnew->screen)); 6013 6014 /* DESCO Sys#67660 6015 * Zero out the entire "keyboard" component of "wnew" widget. 6016 */ 6017 memset(&wnew->keyboard, 0, sizeof(wnew->keyboard)); 6018 6019 /* dummy values so that we don't try to Realize the parent shell with height 6020 * or width of 0, which is illegal in X. The real size is computed in the 6021 * xtermWidget's Realize proc, but the shell's Realize proc is called first, 6022 * and must see a valid size. 6023 */ 6024 wnew->core.height = wnew->core.width = 1; 6025 6026 /* 6027 * The definition of -rv now is that it changes the definition of 6028 * XtDefaultForeground and XtDefaultBackground. So, we no longer 6029 * need to do anything special. 6030 */ 6031 TScreenOf(wnew)->display = wnew->core.screen->display; 6032 6033 /* 6034 * We use the default foreground/background colors to compare/check if a 6035 * color-resource has been set. 6036 */ 6037#define MyBlackPixel(dpy) BlackPixel(dpy,DefaultScreen(dpy)) 6038#define MyWhitePixel(dpy) WhitePixel(dpy,DefaultScreen(dpy)) 6039 6040 if (request->misc.re_verse) { 6041 wnew->dft_foreground = MyWhitePixel(TScreenOf(wnew)->display); 6042 wnew->dft_background = MyBlackPixel(TScreenOf(wnew)->display); 6043 } else { 6044 wnew->dft_foreground = MyBlackPixel(TScreenOf(wnew)->display); 6045 wnew->dft_background = MyWhitePixel(TScreenOf(wnew)->display); 6046 } 6047 init_Tres(TEXT_FG); 6048 init_Tres(TEXT_BG); 6049 6050 TRACE(("Color resource initialization:\n")); 6051 TRACE((" Default foreground %#lx\n", wnew->dft_foreground)); 6052 TRACE((" Default background %#lx\n", wnew->dft_background)); 6053 TRACE((" Screen foreground %#lx\n", T_COLOR(TScreenOf(wnew), TEXT_FG))); 6054 TRACE((" Screen background %#lx\n", T_COLOR(TScreenOf(wnew), TEXT_BG))); 6055 6056 TScreenOf(wnew)->mouse_button = -1; 6057 TScreenOf(wnew)->mouse_row = -1; 6058 TScreenOf(wnew)->mouse_col = -1; 6059 6060#if OPT_BOX_CHARS 6061 init_Bres(screen.force_box_chars); 6062 init_Bres(screen.force_packed); 6063 init_Bres(screen.force_all_chars); 6064#endif 6065 init_Bres(screen.free_bold_box); 6066 6067 init_Bres(screen.c132); 6068 init_Bres(screen.curses); 6069 init_Bres(screen.hp_ll_bc); 6070#if OPT_XMC_GLITCH 6071 init_Ires(screen.xmc_glitch); 6072 init_Ires(screen.xmc_attributes); 6073 init_Bres(screen.xmc_inline); 6074 init_Bres(screen.move_sgr_ok); 6075#endif 6076#if OPT_BLINK_CURS 6077 init_Bres(screen.cursor_blink); 6078 init_Ires(screen.blink_on); 6079 init_Ires(screen.blink_off); 6080 TScreenOf(wnew)->cursor_blink_res = TScreenOf(wnew)->cursor_blink; 6081#endif 6082 init_Bres(screen.cursor_underline); 6083#if OPT_BLINK_TEXT 6084 init_Ires(screen.blink_as_bold); 6085#endif 6086 init_Ires(screen.border); 6087 init_Bres(screen.jumpscroll); 6088 init_Bres(screen.fastscroll); 6089 init_Bres(screen.old_fkeys); 6090 init_Bres(screen.delete_is_del); 6091 wnew->keyboard.type = TScreenOf(wnew)->old_fkeys 6092 ? keyboardIsLegacy 6093 : keyboardIsDefault; 6094#ifdef ALLOWLOGGING 6095 init_Bres(misc.logInhibit); 6096 init_Bres(misc.log_on); 6097 init_Sres(screen.logfile); 6098#endif 6099 init_Bres(screen.bellIsUrgent); 6100 init_Bres(screen.bellOnReset); 6101 init_Bres(screen.marginbell); 6102 init_Bres(screen.multiscroll); 6103 init_Ires(screen.nmarginbell); 6104 init_Ires(screen.savelines); 6105 init_Ires(screen.scrollBarBorder); 6106 init_Ires(screen.scrolllines); 6107 init_Bres(screen.scrollttyoutput); 6108 init_Bres(screen.scrollkey); 6109 6110 init_Bres(misc.autoWrap); 6111 init_Bres(misc.login_shell); 6112 init_Bres(misc.reverseWrap); 6113 init_Bres(misc.scrollbar); 6114 init_Sres(misc.geo_metry); 6115 init_Sres(misc.T_geometry); 6116 6117 init_Sres(screen.term_id); 6118 for (s = TScreenOf(request)->term_id; *s; s++) { 6119 if (!isalpha(CharOf(*s))) 6120 break; 6121 } 6122 TScreenOf(wnew)->terminal_id = atoi(s); 6123 if (TScreenOf(wnew)->terminal_id < MIN_DECID) 6124 TScreenOf(wnew)->terminal_id = MIN_DECID; 6125 if (TScreenOf(wnew)->terminal_id > MAX_DECID) 6126 TScreenOf(wnew)->terminal_id = MAX_DECID; 6127 TRACE(("term_id '%s' -> terminal_id %d\n", 6128 TScreenOf(wnew)->term_id, 6129 TScreenOf(wnew)->terminal_id)); 6130 6131 TScreenOf(wnew)->vtXX_level = (TScreenOf(wnew)->terminal_id / 100); 6132 6133 init_Ires(screen.title_modes); 6134 init_Bres(screen.visualbell); 6135 init_Ires(screen.visualBellDelay); 6136 init_Bres(screen.poponbell); 6137 init_Ires(misc.limit_resize); 6138 6139#if OPT_NUM_LOCK 6140 init_Bres(misc.real_NumLock); 6141 init_Bres(misc.alwaysUseMods); 6142 wnew->misc.num_lock = 0; 6143 wnew->misc.alt_mods = 0; 6144 wnew->misc.meta_mods = 0; 6145 wnew->misc.other_mods = 0; 6146#endif 6147 6148#if OPT_INPUT_METHOD 6149 init_Bres(misc.open_im); 6150 init_Ires(misc.retry_im); 6151 init_Sres(misc.f_x); 6152 init_Sres(misc.input_method); 6153 init_Sres(misc.preedit_type); 6154#endif 6155 6156#if OPT_SHIFT_FONTS 6157 init_Bres(misc.shift_fonts); 6158#endif 6159#if OPT_SUNPC_KBD 6160 init_Ires(misc.ctrl_fkeys); 6161#endif 6162#if OPT_TEK4014 6163 TEK4014_SHOWN(wnew) = False; /* not a resource... */ 6164 init_Bres(misc.tekInhibit); 6165 init_Bres(misc.tekSmall); 6166 init_Bres(misc.TekEmu); 6167#endif 6168#if OPT_TCAP_QUERY 6169 TScreenOf(wnew)->tc_query_code = -1; 6170#endif 6171 wnew->misc.re_verse0 = request->misc.re_verse; 6172 init_Bres(misc.re_verse); 6173 init_Ires(screen.multiClickTime); 6174 init_Ires(screen.bellSuppressTime); 6175 init_Sres(screen.charClass); 6176 6177 init_Bres(screen.always_highlight); 6178 init_Bres(screen.brokenSelections); 6179 init_Bres(screen.cutNewline); 6180 init_Bres(screen.cutToBeginningOfLine); 6181 init_Bres(screen.highlight_selection); 6182 init_Bres(screen.show_wrap_marks); 6183 init_Bres(screen.i18nSelections); 6184 init_Bres(screen.keepSelection); 6185 init_Bres(screen.selectToClipboard); 6186 init_Bres(screen.trim_selection); 6187 6188 TScreenOf(wnew)->pointer_cursor = TScreenOf(request)->pointer_cursor; 6189 init_Ires(screen.pointer_mode); 6190 6191 init_Sres(screen.answer_back); 6192 6193 init_Sres(screen.printer_command); 6194 init_Bres(screen.printer_autoclose); 6195 init_Bres(screen.printer_extent); 6196 init_Bres(screen.printer_formfeed); 6197 init_Bres(screen.printer_newline); 6198 init_Ires(screen.printer_controlmode); 6199#if OPT_PRINT_COLORS 6200 init_Ires(screen.print_attributes); 6201#endif 6202 6203 init_Sres(screen.keyboard_dialect); 6204 6205 init_Bres(screen.input_eight_bits); 6206 init_Bres(screen.output_eight_bits); 6207 init_Bres(screen.control_eight_bits); 6208 init_Bres(screen.backarrow_key); 6209 init_Bres(screen.alt_is_not_meta); 6210 init_Bres(screen.alt_sends_esc); 6211 init_Bres(screen.meta_sends_esc); 6212 6213 init_Bres(screen.allowSendEvent0); 6214 init_Bres(screen.allowColorOp0); 6215 init_Bres(screen.allowFontOp0); 6216 init_Bres(screen.allowTcapOp0); 6217 init_Bres(screen.allowTitleOp0); 6218 init_Bres(screen.allowWindowOp0); 6219 6220#if OPT_SCROLL_LOCK 6221 init_Bres(screen.allowScrollLock0); 6222#endif 6223 6224 init_Sres(screen.disallowedColorOps); 6225 6226 set_flags_from_list(TScreenOf(wnew)->disallow_color_ops, 6227 TScreenOf(wnew)->disallowedColorOps, 6228 tblColorOps, 6229 ecLAST); 6230 6231 init_Sres(screen.disallowedFontOps); 6232 6233 set_flags_from_list(TScreenOf(wnew)->disallow_font_ops, 6234 TScreenOf(wnew)->disallowedFontOps, 6235 tblFontOps, 6236 efLAST); 6237 6238 init_Sres(screen.disallowedTcapOps); 6239 6240 set_flags_from_list(TScreenOf(wnew)->disallow_tcap_ops, 6241 TScreenOf(wnew)->disallowedTcapOps, 6242 tblTcapOps, 6243 etLAST); 6244 6245 init_Sres(screen.disallowedWinOps); 6246 6247 set_flags_from_list(TScreenOf(wnew)->disallow_win_ops, 6248 TScreenOf(wnew)->disallowedWinOps, 6249 tblWindowOps, 6250 ewLAST); 6251 6252 init_Sres(screen.default_string); 6253 init_Sres(screen.eightbit_select_types); 6254#if OPT_WIDE_CHARS 6255 init_Sres(screen.utf8_select_types); 6256#endif 6257 6258 /* make a copy so that editres cannot change the resource after startup */ 6259 TScreenOf(wnew)->allowSendEvents = TScreenOf(wnew)->allowSendEvent0; 6260 TScreenOf(wnew)->allowColorOps = TScreenOf(wnew)->allowColorOp0; 6261 TScreenOf(wnew)->allowFontOps = TScreenOf(wnew)->allowFontOp0; 6262 TScreenOf(wnew)->allowTcapOps = TScreenOf(wnew)->allowTcapOp0; 6263 TScreenOf(wnew)->allowTitleOps = TScreenOf(wnew)->allowTitleOp0; 6264 TScreenOf(wnew)->allowWindowOps = TScreenOf(wnew)->allowWindowOp0; 6265 6266#if OPT_SCROLL_LOCK 6267 TScreenOf(wnew)->allowScrollLock = TScreenOf(wnew)->allowScrollLock0; 6268#endif 6269 6270 init_Bres(screen.quiet_grab); 6271 6272#ifndef NO_ACTIVE_ICON 6273 init_Sres(screen.icon_fontname); 6274 TScreenOf(wnew)->fnt_icon.fs = XLoadQueryFont(TScreenOf(wnew)->display, 6275 TScreenOf(wnew)->icon_fontname); 6276 TRACE(("iconFont '%s' %sloaded successfully\n", 6277 TScreenOf(wnew)->icon_fontname, 6278 TScreenOf(wnew)->fnt_icon.fs ? "" : "NOT ")); 6279 init_Bres(misc.active_icon); 6280 init_Ires(misc.icon_border_width); 6281 wnew->misc.icon_border_pixel = request->misc.icon_border_pixel; 6282#endif /* NO_ACTIVE_ICON */ 6283 6284 init_Bres(misc.signalInhibit); 6285 init_Bres(misc.titeInhibit); 6286 init_Bres(misc.tiXtraScroll); 6287 init_Bres(misc.dynamicColors); 6288 for (i = fontMenu_font1; i <= fontMenu_lastBuiltin; i++) { 6289 init_Sres2(screen.MenuFontName, i); 6290 } 6291 init_Ires(misc.fontWarnings); 6292#define DefaultFontNames TScreenOf(wnew)->menu_font_names[fontMenu_default] 6293 init_Sres(misc.default_font.f_n); 6294 init_Sres(misc.default_font.f_b); 6295 DefaultFontNames[fNorm] = x_strdup(wnew->misc.default_font.f_n); 6296 DefaultFontNames[fBold] = x_strdup(wnew->misc.default_font.f_b); 6297#if OPT_WIDE_CHARS 6298 init_Sres(misc.default_font.f_w); 6299 init_Sres(misc.default_font.f_wb); 6300 DefaultFontNames[fWide] = x_strdup(wnew->misc.default_font.f_w); 6301 DefaultFontNames[fWBold] = x_strdup(wnew->misc.default_font.f_wb); 6302#endif 6303 TScreenOf(wnew)->MenuFontName(fontMenu_fontescape) = NULL; 6304 TScreenOf(wnew)->MenuFontName(fontMenu_fontsel) = NULL; 6305 6306 TScreenOf(wnew)->menu_font_number = fontMenu_default; 6307 init_Sres(screen.initial_font); 6308 if (TScreenOf(wnew)->initial_font != 0) { 6309 int result = xtermGetFont(TScreenOf(wnew)->initial_font); 6310 if (result >= 0) 6311 TScreenOf(wnew)->menu_font_number = result; 6312 } 6313#if OPT_BROKEN_OSC 6314 init_Bres(screen.brokenLinuxOSC); 6315#endif 6316 6317#if OPT_BROKEN_ST 6318 init_Bres(screen.brokenStringTerm); 6319#endif 6320 6321#if OPT_C1_PRINT 6322 init_Bres(screen.c1_printable); 6323#endif 6324 6325#if OPT_CLIP_BOLD 6326 init_Bres(screen.use_clipping); 6327#endif 6328 6329#if OPT_DEC_CHRSET 6330 init_Bres(screen.font_doublesize); 6331 init_Ires(screen.cache_doublesize); 6332 if (TScreenOf(wnew)->cache_doublesize > NUM_CHRSET) 6333 TScreenOf(wnew)->cache_doublesize = NUM_CHRSET; 6334 if (TScreenOf(wnew)->cache_doublesize == 0) 6335 TScreenOf(wnew)->font_doublesize = False; 6336 TRACE(("Doublesize%s enabled, up to %d fonts\n", 6337 TScreenOf(wnew)->font_doublesize ? "" : " not", 6338 TScreenOf(wnew)->cache_doublesize)); 6339#endif 6340 6341#if OPT_ISO_COLORS 6342 init_Ires(screen.veryBoldColors); 6343 init_Bres(screen.boldColors); 6344 init_Bres(screen.colorAttrMode); 6345 init_Bres(screen.colorBDMode); 6346 init_Bres(screen.colorBLMode); 6347 init_Bres(screen.colorMode); 6348 init_Bres(screen.colorULMode); 6349 init_Bres(screen.italicULMode); 6350 init_Bres(screen.colorRVMode); 6351 6352#if OPT_COLOR_RES2 6353 TRACE(("...will fake resources for color%d to color%d\n", 6354 MIN_ANSI_COLORS, 6355 NUM_ANSI_COLORS - 1)); 6356#endif 6357 for (i = 0, color_ok = False; i < MAXCOLORS; i++) { 6358 6359#if OPT_COLOR_RES2 6360 /* 6361 * Xt has a hardcoded limit on the maximum number of resources that can 6362 * be used in a widget. If we configure both luit (which implies 6363 * wide-characters) and 256-colors, it goes over that limit. Most 6364 * people would not need a resource-file with 256-colors; the default 6365 * values in our table are sufficient. In that case, fake the resource 6366 * setting by copying the default value from the table. The #define's 6367 * can be overridden to make these true resources. 6368 */ 6369 if (i >= MIN_ANSI_COLORS && i < NUM_ANSI_COLORS) { 6370 TScreenOf(wnew)->Acolors[i].resource = 6371 x_strtrim(fake_resources[i - MIN_ANSI_COLORS].default_addr); 6372 if (TScreenOf(wnew)->Acolors[i].resource == 0) 6373 TScreenOf(wnew)->Acolors[i].resource = XtDefaultForeground; 6374 } else 6375#endif /* OPT_COLOR_RES2 */ 6376 { 6377 TScreenOf(wnew)->Acolors[i] = TScreenOf(request)->Acolors[i]; 6378 TScreenOf(wnew)->Acolors[i].resource = 6379 x_strtrim(TScreenOf(wnew)->Acolors[i].resource); 6380 } 6381 6382#if OPT_COLOR_RES 6383 TRACE(("Acolors[%d] = %s\n", i, TScreenOf(wnew)->Acolors[i].resource)); 6384 TScreenOf(wnew)->Acolors[i].mode = False; 6385 if (DftFg(Acolors[i])) { 6386 TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_FG); 6387 TScreenOf(wnew)->Acolors[i].mode = True; 6388 } else if (DftBg(Acolors[i])) { 6389 TScreenOf(wnew)->Acolors[i].value = T_COLOR(TScreenOf(wnew), TEXT_BG); 6390 TScreenOf(wnew)->Acolors[i].mode = True; 6391 } else { 6392 color_ok = True; 6393 } 6394#else 6395 TRACE(("Acolors[%d] = %#lx\n", i, TScreenOf(request)->Acolors[i])); 6396 if (TScreenOf(wnew)->Acolors[i] != wnew->dft_foreground && 6397 TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_FG) && 6398 TScreenOf(wnew)->Acolors[i] != T_COLOR(TScreenOf(wnew), TEXT_BG)) 6399 color_ok = True; 6400#endif 6401 } 6402 6403 /* 6404 * Check if we're trying to use color in a monochrome screen. Disable 6405 * color in that case, since that would make ANSI colors unusable. A 4-bit 6406 * or 8-bit display is usable, so we do not have to check for anything more 6407 * specific. 6408 */ 6409 if (color_ok) { 6410 Display *display = TScreenOf(wnew)->display; 6411 XVisualInfo myTemplate, *visInfoPtr; 6412 int numFound; 6413 6414 myTemplate.visualid = XVisualIDFromVisual(DefaultVisual(display, 6415 XDefaultScreen(display))); 6416 visInfoPtr = XGetVisualInfo(display, (long) VisualIDMask, 6417 &myTemplate, &numFound); 6418 if (visInfoPtr == 0 6419 || numFound == 0 6420 || visInfoPtr->depth <= 1) { 6421 TRACE(("disabling color since screen is monochrome\n")); 6422 color_ok = False; 6423 } else { 6424 XFree(visInfoPtr); 6425 } 6426 } 6427 6428 /* If none of the colors are anything other than the foreground or 6429 * background, we'll assume this isn't color, no matter what the colorMode 6430 * resource says. (There doesn't seem to be any good way to determine if 6431 * the resource lookup failed versus the user having misconfigured this). 6432 */ 6433 if (!color_ok) { 6434 TScreenOf(wnew)->colorMode = False; 6435 TRACE(("All colors are foreground or background: disable colorMode\n")); 6436 } 6437 wnew->sgr_foreground = -1; 6438 wnew->sgr_background = -1; 6439 wnew->sgr_extended = False; 6440#endif /* OPT_ISO_COLORS */ 6441 6442 /* 6443 * Decode the resources that control the behavior on multiple mouse clicks. 6444 * A single click is always bound to normal character selection, but the 6445 * other flavors can be changed. 6446 */ 6447 for (i = 0; i < NSELECTUNITS; ++i) { 6448 int ck = (i + 1); 6449 TScreenOf(wnew)->maxClicks = ck; 6450 if (i == Select_CHAR) 6451 TScreenOf(wnew)->selectMap[i] = Select_CHAR; 6452 else if (TScreenOf(request)->onClick[i] != 0) 6453 ParseOnClicks(wnew, request, (unsigned) i); 6454 else if (i <= Select_LINE) 6455 TScreenOf(wnew)->selectMap[i] = (SelectUnit) i; 6456 else 6457 break; 6458 TRACE(("on%dClicks %s=%d\n", ck, 6459 NonNull(TScreenOf(request)->onClick[i]), 6460 TScreenOf(wnew)->selectMap[i])); 6461 if (TScreenOf(wnew)->selectMap[i] == NSELECTUNITS) 6462 break; 6463 } 6464 TRACE(("maxClicks %d\n", TScreenOf(wnew)->maxClicks)); 6465 6466 init_Tres(MOUSE_FG); 6467 init_Tres(MOUSE_BG); 6468 init_Tres(TEXT_CURSOR); 6469#if OPT_HIGHLIGHT_COLOR 6470 init_Tres(HIGHLIGHT_BG); 6471 init_Tres(HIGHLIGHT_FG); 6472 init_Bres(screen.hilite_reverse); 6473 init_Bres(screen.hilite_color); 6474 if (TScreenOf(wnew)->hilite_color == Maybe) { 6475 TScreenOf(wnew)->hilite_color = False; 6476#if OPT_COLOR_RES 6477 /* 6478 * If the highlight text/background are both set, and if they are 6479 * not equal to either the text/background or background/text, then 6480 * set the highlightColorMode automatically. 6481 */ 6482 if (!DftFg(Tcolors[HIGHLIGHT_BG]) 6483 && !DftBg(Tcolors[HIGHLIGHT_FG]) 6484 && !TxtFg(Tcolors[HIGHLIGHT_BG]) 6485 && !TxtBg(Tcolors[HIGHLIGHT_FG]) 6486 && !TxtBg(Tcolors[HIGHLIGHT_BG]) 6487 && !TxtFg(Tcolors[HIGHLIGHT_FG])) { 6488 TRACE(("...setting hilite_color automatically\n")); 6489 TScreenOf(wnew)->hilite_color = True; 6490 } 6491#endif 6492 } 6493#endif 6494 6495#if OPT_TEK4014 6496 /* 6497 * The Tek4014 window has no separate resources for foreground, background 6498 * and cursor color. Since xterm always creates the vt100 widget first, we 6499 * can set the Tektronix colors here. That lets us use escape sequences to 6500 * set its dynamic colors and get consistent behavior whether or not the 6501 * window is displayed. 6502 */ 6503 TScreenOf(wnew)->Tcolors[TEK_BG] = TScreenOf(wnew)->Tcolors[TEXT_BG]; 6504 TScreenOf(wnew)->Tcolors[TEK_FG] = TScreenOf(wnew)->Tcolors[TEXT_FG]; 6505 TScreenOf(wnew)->Tcolors[TEK_CURSOR] = TScreenOf(wnew)->Tcolors[TEXT_CURSOR]; 6506#endif 6507 6508#ifdef SCROLLBAR_RIGHT 6509 init_Bres(misc.useRight); 6510#endif 6511 6512#if OPT_RENDERFONT 6513 for (i = 0; i <= fontMenu_lastBuiltin; ++i) { 6514 init_Dres2(misc.face_size, i); 6515 } 6516 init_Sres(misc.face_name); 6517 init_Sres(misc.face_wide_name); 6518 init_Sres(misc.render_font_s); 6519 wnew->misc.render_font = 6520 (Boolean) extendedBoolean(wnew->misc.render_font_s, 6521 tblRenderFont, erLast); 6522 if (wnew->misc.render_font == erDefault) { 6523 if (IsEmpty(wnew->misc.face_name)) { 6524 wnew->misc.face_name = x_strdup(DEFFACENAME_AUTO); 6525 TRACE(("will allow runtime switch to render_font using \"%s\"\n", 6526 wnew->misc.face_name)); 6527 } else { 6528 wnew->misc.render_font = erTrue; 6529 TRACE(("initially using TrueType font\n")); 6530 } 6531 } 6532 /* minor tweak to make debug traces consistent: */ 6533 if (wnew->misc.render_font) { 6534 if (IsEmpty(wnew->misc.face_name)) { 6535 wnew->misc.render_font = False; 6536 TRACE(("reset render_font since there is no face_name\n")); 6537 } 6538 } 6539#endif 6540 6541#if OPT_WIDE_CHARS 6542 VTInitialize_locale(request); 6543 init_Bres(screen.utf8_latin1); 6544 init_Bres(screen.utf8_title); 6545 6546#if OPT_LUIT_PROG 6547 init_Bres(misc.callfilter); 6548 init_Bres(misc.use_encoding); 6549 init_Sres(misc.locale_str); 6550 init_Sres(misc.localefilter); 6551#endif 6552 6553 init_Ires(screen.utf8_inparse); 6554 init_Ires(screen.utf8_mode); 6555 init_Ires(screen.max_combining); 6556 6557 if (TScreenOf(wnew)->max_combining < 0) { 6558 TScreenOf(wnew)->max_combining = 0; 6559 } 6560 if (TScreenOf(wnew)->max_combining > 5) { 6561 TScreenOf(wnew)->max_combining = 5; 6562 } 6563 6564 init_Bres(screen.vt100_graphics); 6565 init_Bres(screen.wide_chars); 6566 init_Bres(misc.mk_width); 6567 init_Bres(misc.cjk_width); 6568 6569 init_Ires(misc.mk_samplesize); 6570 init_Ires(misc.mk_samplepass); 6571 6572 if (wnew->misc.mk_samplesize > 0xffff) 6573 wnew->misc.mk_samplesize = 0xffff; 6574 if (wnew->misc.mk_samplesize < 0) 6575 wnew->misc.mk_samplesize = 0; 6576 6577 if (wnew->misc.mk_samplepass > wnew->misc.mk_samplesize) 6578 wnew->misc.mk_samplepass = wnew->misc.mk_samplesize; 6579 if (wnew->misc.mk_samplepass < 0) 6580 wnew->misc.mk_samplepass = 0; 6581 6582 if (TScreenOf(request)->utf8_mode) { 6583 TRACE(("setting wide_chars on\n")); 6584 TScreenOf(wnew)->wide_chars = True; 6585 } else { 6586 TRACE(("setting utf8_mode to 0\n")); 6587 TScreenOf(wnew)->utf8_mode = uFalse; 6588 } 6589 TRACE(("initialized UTF-8 mode to %d\n", TScreenOf(wnew)->utf8_mode)); 6590 6591#if OPT_MINI_LUIT 6592 if (TScreenOf(request)->latin9_mode) { 6593 TScreenOf(wnew)->latin9_mode = True; 6594 } 6595 if (TScreenOf(request)->unicode_font) { 6596 TScreenOf(wnew)->unicode_font = True; 6597 } 6598 TRACE(("initialized Latin9 mode to %d\n", TScreenOf(wnew)->latin9_mode)); 6599 TRACE(("initialized unicode_font to %d\n", TScreenOf(wnew)->unicode_font)); 6600#endif 6601 6602 decode_wcwidth(wnew); 6603#endif /* OPT_WIDE_CHARS */ 6604 6605 init_Bres(screen.always_bold_mode); 6606 init_Bres(screen.bold_mode); 6607 init_Bres(screen.underline); 6608 6609 wnew->cur_foreground = 0; 6610 wnew->cur_background = 0; 6611 6612 wnew->keyboard.flags = MODE_SRM; 6613 if (TScreenOf(wnew)->backarrow_key) 6614 wnew->keyboard.flags |= MODE_DECBKM; 6615 TRACE(("initialized DECBKM %s\n", 6616 BtoS(wnew->keyboard.flags & MODE_DECBKM))); 6617 6618 /* look for focus related events on the shell, because we need 6619 * to care about the shell's border being part of our focus. 6620 */ 6621 TRACE(("adding event handlers for my_parent %p\n", (void *) my_parent)); 6622 XtAddEventHandler(my_parent, EnterWindowMask, False, 6623 HandleEnterWindow, (Opaque) NULL); 6624 XtAddEventHandler(my_parent, LeaveWindowMask, False, 6625 HandleLeaveWindow, (Opaque) NULL); 6626 XtAddEventHandler(my_parent, FocusChangeMask, False, 6627 HandleFocusChange, (Opaque) NULL); 6628 XtAddEventHandler((Widget) wnew, 0L, True, 6629 VTNonMaskableEvent, (Opaque) NULL); 6630 XtAddEventHandler((Widget) wnew, PropertyChangeMask, False, 6631 HandleBellPropertyChange, (Opaque) NULL); 6632 6633#if HANDLE_STRUCT_NOTIFY 6634#if OPT_TOOLBAR 6635 wnew->VT100_TB_INFO(menu_bar) = request->VT100_TB_INFO(menu_bar); 6636 init_Ires(VT100_TB_INFO(menu_height)); 6637#else 6638 /* Flag icon name with "***" on window output when iconified. 6639 * Put in a handler that will tell us when we get Map/Unmap events. 6640 */ 6641 if (resource.zIconBeep) 6642#endif 6643 XtAddEventHandler(my_parent, StructureNotifyMask, False, 6644 HandleStructNotify, (Opaque) 0); 6645#endif /* HANDLE_STRUCT_NOTIFY */ 6646 6647 TScreenOf(wnew)->bellInProgress = False; 6648 6649 set_character_class(TScreenOf(wnew)->charClass); 6650 6651 /* create it, but don't realize it */ 6652 ScrollBarOn(wnew, True); 6653 6654 /* make sure that the resize gravity acceptable */ 6655 if (!GravityIsNorthWest(wnew) && 6656 !GravityIsSouthWest(wnew)) { 6657 char value[80]; 6658 String temp[2]; 6659 Cardinal nparams = 1; 6660 6661 sprintf(value, "%d", wnew->misc.resizeGravity); 6662 temp[0] = value; 6663 temp[1] = 0; 6664 XtAppWarningMsg(app_con, "rangeError", "resizeGravity", "XTermError", 6665 "unsupported resizeGravity resource value (%s)", 6666 temp, &nparams); 6667 wnew->misc.resizeGravity = SouthWestGravity; 6668 } 6669#ifndef NO_ACTIVE_ICON 6670 TScreenOf(wnew)->whichVwin = &TScreenOf(wnew)->fullVwin; 6671#endif /* NO_ACTIVE_ICON */ 6672 6673 if (TScreenOf(wnew)->savelines < 0) 6674 TScreenOf(wnew)->savelines = 0; 6675 6676 init_Bres(screen.awaitInput); 6677 6678 wnew->flags = 0; 6679 if (!TScreenOf(wnew)->jumpscroll) 6680 wnew->flags |= SMOOTHSCROLL; 6681 if (wnew->misc.reverseWrap) 6682 wnew->flags |= REVERSEWRAP; 6683 if (wnew->misc.autoWrap) 6684 wnew->flags |= WRAPAROUND; 6685 if (wnew->misc.re_verse != wnew->misc.re_verse0) 6686 wnew->flags |= REVERSE_VIDEO; 6687 if (TScreenOf(wnew)->c132) 6688 wnew->flags |= IN132COLUMNS; 6689 6690 wnew->initflags = wnew->flags; 6691 6692#if OPT_MOD_FKEYS 6693 init_Ires(keyboard.modify_1st.cursor_keys); 6694 init_Ires(keyboard.modify_1st.function_keys); 6695 init_Ires(keyboard.modify_1st.keypad_keys); 6696 init_Ires(keyboard.modify_1st.other_keys); 6697 init_Ires(keyboard.modify_1st.string_keys); 6698 init_Ires(keyboard.format_keys); 6699 wnew->keyboard.modify_now = wnew->keyboard.modify_1st; 6700#endif 6701 6702 init_Ires(misc.appcursorDefault); 6703 if (wnew->misc.appcursorDefault) 6704 wnew->keyboard.flags |= MODE_DECCKM; 6705 6706 init_Ires(misc.appkeypadDefault); 6707 if (wnew->misc.appkeypadDefault) 6708 wnew->keyboard.flags |= MODE_DECKPAM; 6709 6710 initLineData(wnew); 6711 return; 6712} 6713 6714void 6715releaseCursorGCs(XtermWidget xw) 6716{ 6717 TScreen *screen = TScreenOf(xw); 6718 VTwin *win = WhichVWin(screen); 6719 int n; 6720 6721 for_each_curs_gc(n) { 6722 freeCgs(xw, win, (CgsEnum) n); 6723 } 6724} 6725 6726void 6727releaseWindowGCs(XtermWidget xw, VTwin * win) 6728{ 6729 int n; 6730 6731 for_each_text_gc(n) { 6732 freeCgs(xw, win, (CgsEnum) n); 6733 } 6734} 6735 6736#define TRACE_FREE_LEAK(name) \ 6737 if (name) { \ 6738 free((void *) name); \ 6739 name = 0; \ 6740 TRACE(("freed " #name "\n")); \ 6741 } 6742 6743#define FREE_LEAK(name) \ 6744 if (name) { \ 6745 free((void *) name); \ 6746 name = 0; \ 6747 } 6748 6749#if OPT_INPUT_METHOD 6750static void 6751cleanupInputMethod(TScreen * screen) 6752{ 6753 if (screen->xim) { 6754 XCloseIM(screen->xim); 6755 screen->xim = 0; 6756 TRACE(("freed screen->xim\n")); 6757 } 6758} 6759#endif 6760 6761static void 6762VTDestroy(Widget w GCC_UNUSED) 6763{ 6764#ifdef NO_LEAKS 6765 XtermWidget xw = (XtermWidget) w; 6766 TScreen *screen = TScreenOf(xw); 6767 Cardinal n; 6768 6769 StopBlinking(screen); 6770 6771 if (screen->scrollWidget) { 6772 XtUninstallTranslations(screen->scrollWidget); 6773 XtDestroyWidget(screen->scrollWidget); 6774 } 6775#if OPT_FIFO_LINES 6776 while (screen->saved_fifo-- > 0) { 6777 deleteScrollback(screen, 0); 6778 } 6779#endif 6780 while (screen->save_title != 0) { 6781 SaveTitle *last = screen->save_title; 6782 screen->save_title = last->next; 6783 free(last->iconName); 6784 free(last->windowName); 6785 free(last); 6786 } 6787 TRACE_FREE_LEAK(screen->save_ptr); 6788 TRACE_FREE_LEAK(screen->saveBuf_data); 6789 TRACE_FREE_LEAK(screen->saveBuf_index); 6790 for (n = 0; n < 2; ++n) { 6791 TRACE_FREE_LEAK(screen->editBuf_data[n]); 6792 TRACE_FREE_LEAK(screen->editBuf_index[n]); 6793 } 6794 TRACE_FREE_LEAK(screen->keyboard_dialect); 6795 TRACE_FREE_LEAK(screen->term_id); 6796#if OPT_WIDE_CHARS 6797#if OPT_LUIT_PROG 6798 TRACE_FREE_LEAK(xw->misc.locale_str); 6799 TRACE_FREE_LEAK(xw->misc.localefilter); 6800#endif 6801#endif 6802#if OPT_INPUT_METHOD 6803 cleanupInputMethod(screen); 6804#endif 6805 releaseCursorGCs(xw); 6806 releaseWindowGCs(xw, &(screen->fullVwin)); 6807#ifndef NO_ACTIVE_ICON 6808 releaseWindowGCs(xw, &(screen->iconVwin)); 6809#endif 6810 XtUninstallTranslations((Widget) xw); 6811#if OPT_TOOLBAR 6812 XtUninstallTranslations((Widget) XtParent(xw)); 6813#endif 6814 XtUninstallTranslations((Widget) SHELL_OF(xw)); 6815 6816 if (screen->hidden_cursor) 6817 XFreeCursor(screen->display, screen->hidden_cursor); 6818 6819 xtermCloseFonts(xw, screen->fnts); 6820 noleaks_cachedCgs(xw); 6821 6822#if OPT_RENDERFONT 6823 for (n = 0; n < NMENUFONTS; ++n) { 6824 xtermCloseXft(screen, &(screen->renderFontNorm[n])); 6825 xtermCloseXft(screen, &(screen->renderFontBold[n])); 6826 xtermCloseXft(screen, &(screen->renderFontItal[n])); 6827#if OPT_RENDERWIDE 6828 xtermCloseXft(screen, &(screen->renderWideNorm[n])); 6829 xtermCloseXft(screen, &(screen->renderWideBold[n])); 6830 xtermCloseXft(screen, &(screen->renderWideItal[n])); 6831#endif 6832 } 6833#endif 6834 6835 /* free things allocated via init_Sres or Init_Sres2 */ 6836#ifdef ALLOWLOGGING 6837 TRACE_FREE_LEAK(screen->logfile); 6838#endif 6839 TRACE_FREE_LEAK(screen->term_id); 6840 TRACE_FREE_LEAK(screen->charClass); 6841 TRACE_FREE_LEAK(screen->answer_back); 6842 TRACE_FREE_LEAK(screen->printer_command); 6843 TRACE_FREE_LEAK(screen->keyboard_dialect); 6844 TRACE_FREE_LEAK(screen->disallowedColorOps); 6845 TRACE_FREE_LEAK(screen->disallowedFontOps); 6846 TRACE_FREE_LEAK(screen->disallowedTcapOps); 6847 TRACE_FREE_LEAK(screen->disallowedWinOps); 6848 TRACE_FREE_LEAK(screen->default_string); 6849 TRACE_FREE_LEAK(screen->eightbit_select_types); 6850#if OPT_WIDE_CHARS 6851 TRACE_FREE_LEAK(screen->utf8_select_types); 6852#endif 6853#if 0 6854 for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; n++) { 6855 TRACE_FREE_LEAK(screen->MenuFontName(n)); 6856 } 6857#endif 6858 TRACE_FREE_LEAK(screen->initial_font); 6859#if OPT_LUIT_PROG 6860 TRACE_FREE_LEAK(xw->misc.locale_str); 6861 TRACE_FREE_LEAK(xw->misc.localefilter); 6862#endif 6863#if OPT_RENDERFONT 6864 TRACE_FREE_LEAK(xw->misc.face_name); 6865 TRACE_FREE_LEAK(xw->misc.face_wide_name); 6866#endif 6867 6868#if OPT_SELECT_REGEX 6869 for (n = 0; n < NSELECTUNITS; ++n) { 6870 FREE_LEAK(screen->selectExpr[n]); 6871 } 6872#endif 6873 6874 if (screen->selection_atoms) 6875 XtFree((char *) (screen->selection_atoms)); 6876 6877 XtFree((char *) (screen->selection_data)); 6878 6879 TRACE_FREE_LEAK(xw->keyboard.extra_translations); 6880 TRACE_FREE_LEAK(xw->keyboard.shell_translations); 6881 TRACE_FREE_LEAK(xw->keyboard.xterm_translations); 6882 6883#if OPT_WIDE_CHARS 6884 FreeTypedBuffer(XChar2b); 6885 FreeTypedBuffer(char); 6886#endif 6887#if OPT_RENDERFONT 6888#if OPT_RENDERWIDE 6889 FreeTypedBuffer(XftCharSpec); 6890#else 6891 FreeTypedBuffer(XftChar8); 6892#endif 6893#endif 6894 6895 TRACE_FREE_LEAK(myState.print_area); 6896 TRACE_FREE_LEAK(myState.string_area); 6897 memset(&myState, 0, sizeof(myState)); 6898 6899#endif /* defined(NO_LEAKS) */ 6900} 6901 6902/*ARGSUSED*/ 6903static void 6904VTRealize(Widget w, 6905 XtValueMask * valuemask, 6906 XSetWindowAttributes * values) 6907{ 6908 XtermWidget xw = (XtermWidget) w; 6909 TScreen *screen = TScreenOf(xw); 6910 6911 const VTFontNames *myfont; 6912 unsigned width, height; 6913 int xpos, ypos, pr; 6914 Atom pid_atom; 6915 int i; 6916 6917 TRACE(("VTRealize\n")); 6918 6919 TabReset(xw->tabs); 6920 6921 if (screen->menu_font_number == fontMenu_default) { 6922 myfont = &(xw->misc.default_font); 6923 } else { 6924 myfont = xtermFontName(screen->MenuFontName(screen->menu_font_number)); 6925 } 6926 memset(screen->fnts, 0, sizeof(screen->fnts)); 6927 6928 if (!xtermLoadFont(xw, 6929 myfont, 6930 False, 6931 screen->menu_font_number)) { 6932 if (XmuCompareISOLatin1(myfont->f_n, DEFFONT) != 0) { 6933 char *use_font = x_strdup(DEFFONT); 6934 fprintf(stderr, 6935 "%s: unable to open font \"%s\", trying \"%s\"....\n", 6936 ProgramName, myfont->f_n, use_font); 6937 (void) xtermLoadFont(xw, 6938 xtermFontName(use_font), 6939 False, 6940 screen->menu_font_number); 6941 screen->MenuFontName(screen->menu_font_number) = use_font; 6942 } 6943 } 6944 6945 /* really screwed if we couldn't open default font */ 6946 if (!screen->fnts[fNorm].fs) { 6947 fprintf(stderr, "%s: unable to locate a suitable font\n", 6948 ProgramName); 6949 Exit(1); 6950 } 6951#if OPT_WIDE_CHARS 6952 if (TScreenOf(xw)->utf8_mode) { 6953 TRACE(("check if this is a wide font, if not try again\n")); 6954 if (xtermLoadWideFonts(xw, False)) 6955 SetVTFont(xw, screen->menu_font_number, True, NULL); 6956 } 6957#endif 6958 6959 /* making cursor */ 6960 if (!screen->pointer_cursor) { 6961 screen->pointer_cursor = 6962 make_colored_cursor(XC_xterm, 6963 T_COLOR(screen, MOUSE_FG), 6964 T_COLOR(screen, MOUSE_BG)); 6965 } else { 6966 recolor_cursor(screen, 6967 screen->pointer_cursor, 6968 T_COLOR(screen, MOUSE_FG), 6969 T_COLOR(screen, MOUSE_BG)); 6970 } 6971 6972 /* set defaults */ 6973 xpos = 1; 6974 ypos = 1; 6975 width = 80; 6976 height = 24; 6977 6978 TRACE(("parsing geo_metry %s\n", NonNull(xw->misc.geo_metry))); 6979 pr = XParseGeometry(xw->misc.geo_metry, &xpos, &ypos, 6980 &width, &height); 6981 TRACE(("... position %d,%d size %dx%d\n", ypos, xpos, height, width)); 6982 6983 set_max_col(screen, (int) (width - 1)); /* units in character cells */ 6984 set_max_row(screen, (int) (height - 1)); /* units in character cells */ 6985 xtermUpdateFontInfo(xw, False); 6986 6987 width = screen->fullVwin.fullwidth; 6988 height = screen->fullVwin.fullheight; 6989 6990 TRACE(("... border widget %d parent %d shell %d\n", 6991 BorderWidth(xw), 6992 BorderWidth(XtParent(xw)), 6993 BorderWidth(SHELL_OF(xw)))); 6994 6995 if ((pr & XValue) && (XNegative & pr)) { 6996 xpos += (DisplayWidth(screen->display, DefaultScreen(screen->display)) 6997 - (int) width 6998 - (BorderWidth(XtParent(xw)) * 2)); 6999 } 7000 if ((pr & YValue) && (YNegative & pr)) { 7001 ypos += (DisplayHeight(screen->display, DefaultScreen(screen->display)) 7002 - (int) height 7003 - (BorderWidth(XtParent(xw)) * 2)); 7004 } 7005 7006 /* set up size hints for window manager; min 1 char by 1 char */ 7007 getXtermSizeHints(xw); 7008 xtermSizeHints(xw, (xw->misc.scrollbar 7009 ? (screen->scrollWidget->core.width 7010 + BorderWidth(screen->scrollWidget)) 7011 : 0)); 7012 7013 xw->hints.x = xpos; 7014 xw->hints.y = ypos; 7015#if OPT_MAXIMIZE 7016 /* assure single-increment resize for fullscreen */ 7017 if (term->screen.fullscreen) { 7018 xw->hints.width_inc = 1; 7019 xw->hints.height_inc = 1; 7020 } 7021#endif 7022 if ((XValue & pr) || (YValue & pr)) { 7023 xw->hints.flags |= USSize | USPosition; 7024 xw->hints.flags |= PWinGravity; 7025 switch (pr & (XNegative | YNegative)) { 7026 case 0: 7027 xw->hints.win_gravity = NorthWestGravity; 7028 break; 7029 case XNegative: 7030 xw->hints.win_gravity = NorthEastGravity; 7031 break; 7032 case YNegative: 7033 xw->hints.win_gravity = SouthWestGravity; 7034 break; 7035 default: 7036 xw->hints.win_gravity = SouthEastGravity; 7037 break; 7038 } 7039 } else { 7040 /* set a default size, but do *not* set position */ 7041 xw->hints.flags |= PSize; 7042 } 7043 xw->hints.height = xw->hints.base_height 7044 + xw->hints.height_inc * MaxRows(screen); 7045 xw->hints.width = xw->hints.base_width 7046 + xw->hints.width_inc * MaxCols(screen); 7047 7048 if ((WidthValue & pr) || (HeightValue & pr)) 7049 xw->hints.flags |= USSize; 7050 else 7051 xw->hints.flags |= PSize; 7052 7053 /* 7054 * Note that the size-hints are for the shell, while the resize-request 7055 * is for the vt100 widget. They are not the same size. 7056 */ 7057 (void) REQ_RESIZE((Widget) xw, 7058 (Dimension) width, (Dimension) height, 7059 &xw->core.width, &xw->core.height); 7060 7061 /* XXX This is bogus. We are parsing geometries too late. This 7062 * is information that the shell widget ought to have before we get 7063 * realized, so that it can do the right thing. 7064 */ 7065 if (xw->hints.flags & USPosition) 7066 XMoveWindow(XtDisplay(xw), VShellWindow(xw), 7067 xw->hints.x, xw->hints.y); 7068 7069 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 7070 TRACE_HINTS(&xw->hints); 7071 XSetWMNormalHints(XtDisplay(xw), VShellWindow(xw), &xw->hints); 7072 TRACE(("%s@%d -- ", __FILE__, __LINE__)); 7073 TRACE_WM_HINTS(xw); 7074 7075 if ((pid_atom = XInternAtom(XtDisplay(xw), "_NET_WM_PID", False)) != None) { 7076 /* XChangeProperty format 32 really is "long" */ 7077 unsigned long pid_l = (unsigned long) getpid(); 7078 TRACE(("Setting _NET_WM_PID property to %lu\n", pid_l)); 7079 XChangeProperty(XtDisplay(xw), VShellWindow(xw), 7080 pid_atom, XA_CARDINAL, 32, PropModeReplace, 7081 (unsigned char *) &pid_l, 1); 7082 } 7083 7084 XFlush(XtDisplay(xw)); /* get it out to window manager */ 7085 7086 /* use ForgetGravity instead of SouthWestGravity because translating 7087 the Expose events for ConfigureNotifys is too hard */ 7088 values->bit_gravity = (GravityIsNorthWest(xw) 7089 ? NorthWestGravity 7090 : ForgetGravity); 7091 TScreenOf(xw)->fullVwin.window = XtWindow(xw) = 7092 XCreateWindow(XtDisplay(xw), XtWindow(XtParent(xw)), 7093 xw->core.x, xw->core.y, 7094 xw->core.width, xw->core.height, BorderWidth(xw), 7095 (int) xw->core.depth, 7096 InputOutput, CopyFromParent, 7097 *valuemask | CWBitGravity, values); 7098 screen->event_mask = values->event_mask; 7099 7100#ifndef NO_ACTIVE_ICON 7101 /* 7102 * Normally, the font-number for icon fonts does not correspond with any of 7103 * the menu-selectable fonts. If we cannot load the font given for the 7104 * iconFont resource, try with font1 aka "Unreadable". 7105 */ 7106 screen->icon_fontnum = -1; 7107 if (screen->fnt_icon.fs == 0) { 7108 screen->fnt_icon.fs = XLoadQueryFont(screen->display, 7109 screen->MenuFontName(fontMenu_font1)); 7110 TRACE(("%susing font1 '%s' as iconFont\n", 7111 (screen->fnt_icon.fs 7112 ? "" 7113 : "NOT "), 7114 screen->MenuFontName(fontMenu_font1))); 7115 } 7116#if OPT_RENDERFONT 7117 /* 7118 * If we still have no result from iconFont resource (perhaps because fonts 7119 * are missing) but are using Xft, try to use that instead. We prefer 7120 * bitmap fonts in any case, since scaled fonts are usually less readable, 7121 * particularly at small sizes. 7122 */ 7123 if (UsingRenderFont(xw) 7124 && screen->fnt_icon.fs == 0) { 7125 screen->icon_fontnum = fontMenu_default; 7126 screen->fnt_icon.fs = screen->fnts[0].fs; /* need for next-if */ 7127 TRACE(("using TrueType font as iconFont\n")); 7128 } 7129#endif 7130 if (xw->misc.active_icon && screen->fnt_icon.fs) { 7131 int iconX = 0, iconY = 0; 7132 Widget shell = SHELL_OF(xw); 7133 VTwin *win = &(screen->iconVwin); 7134 int save_fontnum = screen->menu_font_number; 7135 7136 TRACE(("Initializing active-icon %d\n", screen->icon_fontnum)); 7137 screen->menu_font_number = screen->icon_fontnum; 7138 XtVaGetValues(shell, 7139 XtNiconX, &iconX, 7140 XtNiconY, &iconY, 7141 (XtPointer) 0); 7142 xtermComputeFontInfo(xw, &(screen->iconVwin), screen->fnt_icon.fs, 0); 7143 screen->menu_font_number = save_fontnum; 7144 7145 /* since only one client is permitted to select for Button 7146 * events, we have to let the window manager get 'em... 7147 */ 7148 values->event_mask &= ~(ButtonPressMask | ButtonReleaseMask); 7149 values->border_pixel = xw->misc.icon_border_pixel; 7150 7151 screen->iconVwin.window = 7152 XCreateWindow(XtDisplay(xw), 7153 RootWindowOfScreen(XtScreen(shell)), 7154 iconX, iconY, 7155 screen->iconVwin.fullwidth, 7156 screen->iconVwin.fullheight, 7157 xw->misc.icon_border_width, 7158 (int) xw->core.depth, 7159 InputOutput, CopyFromParent, 7160 *valuemask | CWBitGravity | CWBorderPixel, 7161 values); 7162 XtVaSetValues(shell, 7163 XtNiconWindow, screen->iconVwin.window, 7164 (XtPointer) 0); 7165 XtRegisterDrawable(XtDisplay(xw), screen->iconVwin.window, w); 7166 7167 setCgsFont(xw, win, gcNorm, &(screen->fnt_icon)); 7168 setCgsFore(xw, win, gcNorm, T_COLOR(screen, TEXT_FG)); 7169 setCgsBack(xw, win, gcNorm, T_COLOR(screen, TEXT_BG)); 7170 7171 copyCgs(xw, win, gcBold, gcNorm); 7172 7173 setCgsFont(xw, win, gcNormReverse, &(screen->fnt_icon)); 7174 setCgsFore(xw, win, gcNormReverse, T_COLOR(screen, TEXT_BG)); 7175 setCgsBack(xw, win, gcNormReverse, T_COLOR(screen, TEXT_FG)); 7176 7177 copyCgs(xw, win, gcBoldReverse, gcNormReverse); 7178 7179#if OPT_TOOLBAR 7180 /* 7181 * Toolbar is initialized before we get here. Enable the menu item 7182 * and set it properly. 7183 */ 7184 SetItemSensitivity(vtMenuEntries[vtMenu_activeicon].widget, True); 7185 update_activeicon(); 7186#endif 7187 } else { 7188 TRACE(("Disabled active-icon\n")); 7189 xw->misc.active_icon = False; 7190 } 7191#endif /* NO_ACTIVE_ICON */ 7192 7193#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 7194 VTInitI18N(xw); 7195#else 7196 TScreenOf(xw)->xic = NULL; 7197#endif 7198#if OPT_NUM_LOCK 7199 VTInitModifiers(xw); 7200#if OPT_EXTRA_PASTE 7201 if (xw->keyboard.extra_translations) { 7202 XtOverrideTranslations((Widget) xw, 7203 XtParseTranslationTable(xw->keyboard.extra_translations)); 7204 } 7205#endif 7206#endif 7207 7208 set_cursor_gcs(xw); 7209 7210 /* Reset variables used by ANSI emulation. */ 7211 7212 resetCharsets(screen); 7213 7214 XDefineCursor(screen->display, VShellWindow(xw), screen->pointer_cursor); 7215 7216 set_cur_col(screen, 0); 7217 set_cur_row(screen, 0); 7218 set_max_col(screen, Width(screen) / screen->fullVwin.f_width - 1); 7219 set_max_row(screen, Height(screen) / screen->fullVwin.f_height - 1); 7220 set_tb_margins(screen, 0, screen->max_row); 7221 7222 memset(screen->sc, 0, sizeof(screen->sc)); 7223 7224 /* Mark screen buffer as unallocated. We wait until the run loop so 7225 that the child process does not fork and exec with all the dynamic 7226 memory it will never use. If we were to do it here, the 7227 swap space for new process would be huge for huge savelines. */ 7228#if OPT_TEK4014 7229 if (!tekWidget) /* if not called after fork */ 7230#endif 7231 { 7232 screen->visbuf = NULL; 7233 screen->saveBuf_index = NULL; 7234 } 7235 7236 screen->do_wrap = False; 7237 screen->scrolls = screen->incopy = 0; 7238 xtermSetCursorBox(screen); 7239 7240 screen->savedlines = 0; 7241 7242 for (i = 0; i < 2; ++i) { 7243 screen->whichBuf = !screen->whichBuf; 7244 CursorSave(xw); 7245 } 7246 7247 /* 7248 * Do this last, since it may change the layout via a resize. 7249 */ 7250 if (xw->misc.scrollbar) { 7251 screen->fullVwin.sb_info.width = 0; 7252 ScrollBarOn(xw, False); 7253 } 7254 7255 return; 7256} 7257 7258#if OPT_I18N_SUPPORT && OPT_INPUT_METHOD 7259 7260/* limit this feature to recent XFree86 since X11R6.x core dumps */ 7261#if defined(XtSpecificationRelease) && XtSpecificationRelease >= 6 && defined(X_HAVE_UTF8_STRING) 7262#define USE_XIM_INSTANTIATE_CB 7263 7264static void 7265xim_instantiate_cb(Display * display, 7266 XPointer client_data GCC_UNUSED, 7267 XPointer call_data GCC_UNUSED) 7268{ 7269 if (display != XtDisplay(term)) 7270 return; 7271 7272 VTInitI18N(term); 7273} 7274 7275static void 7276xim_destroy_cb(XIM im GCC_UNUSED, 7277 XPointer client_data GCC_UNUSED, 7278 XPointer call_data GCC_UNUSED) 7279{ 7280 TScreenOf(term)->xic = NULL; 7281 7282 XRegisterIMInstantiateCallback(XtDisplay(term), NULL, NULL, NULL, 7283 xim_instantiate_cb, NULL); 7284} 7285#endif /* X11R6+ */ 7286 7287static void 7288xim_real_init(XtermWidget xw) 7289{ 7290 TScreen *screen = TScreenOf(xw); 7291 unsigned i, j; 7292 char *p, *s, *t, *ns, *end, buf[32]; 7293 XIMStyles *xim_styles; 7294 XIMStyle input_style = 0; 7295 Bool found; 7296 static struct { 7297 const char *name; 7298 unsigned long code; 7299 } known_style[] = { 7300 { 7301 "OverTheSpot", (XIMPreeditPosition | XIMStatusNothing) 7302 }, 7303 { 7304 "OffTheSpot", (XIMPreeditArea | XIMStatusArea) 7305 }, 7306 { 7307 "Root", (XIMPreeditNothing | XIMStatusNothing) 7308 }, 7309 }; 7310 7311 screen->xic = NULL; 7312 7313 if (xw->misc.cannot_im) { 7314 return; 7315 } 7316 7317 if (!xw->misc.input_method || !*xw->misc.input_method) { 7318 if ((p = XSetLocaleModifiers("")) != NULL && *p) 7319 screen->xim = XOpenIM(XtDisplay(xw), NULL, NULL, NULL); 7320 } else { 7321 s = xw->misc.input_method; 7322 i = 5 + (unsigned) strlen(s); 7323 7324 t = (char *) MyStackAlloc(i, buf); 7325 if (t == NULL) { 7326 SysError(ERROR_VINIT); 7327 } else { 7328 7329 for (ns = s; ns && *s;) { 7330 while (*s && isspace(CharOf(*s))) 7331 s++; 7332 if (!*s) 7333 break; 7334 if ((ns = end = strchr(s, ',')) == 0) 7335 end = s + strlen(s); 7336 while ((end != s) && isspace(CharOf(end[-1]))) 7337 end--; 7338 7339 if (end != s) { 7340 strcpy(t, "@im="); 7341 strncat(t, s, (size_t) (end - s)); 7342 7343 if ((p = XSetLocaleModifiers(t)) != 0 && *p 7344 && (screen->xim = XOpenIM(XtDisplay(xw), 7345 NULL, 7346 NULL, 7347 NULL)) != 0) 7348 break; 7349 7350 } 7351 s = ns + 1; 7352 } 7353 MyStackFree(t, buf); 7354 } 7355 } 7356 7357 if (screen->xim == NULL 7358 && (p = XSetLocaleModifiers("@im=none")) != NULL 7359 && *p) { 7360 screen->xim = XOpenIM(XtDisplay(xw), NULL, NULL, NULL); 7361 } 7362 7363 if (!screen->xim) { 7364 fprintf(stderr, "Failed to open input method\n"); 7365 return; 7366 } 7367 TRACE(("VTInitI18N opened input method\n")); 7368 7369 if (XGetIMValues(screen->xim, XNQueryInputStyle, &xim_styles, NULL) 7370 || !xim_styles 7371 || !xim_styles->count_styles) { 7372 fprintf(stderr, "input method doesn't support any style\n"); 7373 cleanupInputMethod(screen); 7374 xw->misc.cannot_im = True; 7375 return; 7376 } 7377 7378 found = False; 7379 for (s = xw->misc.preedit_type; s && !found;) { 7380 while (*s && isspace(CharOf(*s))) 7381 s++; 7382 if (!*s) 7383 break; 7384 if ((ns = end = strchr(s, ',')) != 0) 7385 ns++; 7386 else 7387 end = s + strlen(s); 7388 while ((end != s) && isspace(CharOf(end[-1]))) 7389 end--; 7390 7391 if (end != s) { /* just in case we have a spurious comma */ 7392 TRACE(("looking for style '%.*s'\n", (int) (end - s), s)); 7393 for (i = 0; i < XtNumber(known_style); i++) { 7394 if ((int) strlen(known_style[i].name) == (end - s) 7395 && !strncmp(s, known_style[i].name, (size_t) (end - s))) { 7396 input_style = known_style[i].code; 7397 for (j = 0; j < xim_styles->count_styles; j++) { 7398 if (input_style == xim_styles->supported_styles[j]) { 7399 found = True; 7400 break; 7401 } 7402 } 7403 if (found) 7404 break; 7405 } 7406 } 7407 } 7408 7409 s = ns; 7410 } 7411 XFree(xim_styles); 7412 7413 if (!found) { 7414 fprintf(stderr, 7415 "input method doesn't support my preedit type (%s)\n", 7416 xw->misc.preedit_type); 7417 cleanupInputMethod(screen); 7418 xw->misc.cannot_im = True; 7419 return; 7420 } 7421 7422 /* 7423 * Check for styles we do not yet support. 7424 */ 7425 TRACE(("input_style %#lx\n", input_style)); 7426 if (input_style == (XIMPreeditArea | XIMStatusArea)) { 7427 fprintf(stderr, 7428 "This program doesn't support the 'OffTheSpot' preedit type\n"); 7429 cleanupInputMethod(screen); 7430 xw->misc.cannot_im = True; 7431 return; 7432 } 7433 7434 /* 7435 * For XIMPreeditPosition (or OverTheSpot), XIM client has to 7436 * prepare a font. 7437 * The font has to be locale-dependent XFontSet, whereas 7438 * XTerm use Unicode font. This leads a problem that the 7439 * same font cannot be used for XIM preedit. 7440 */ 7441 if (input_style != (XIMPreeditNothing | XIMStatusNothing)) { 7442 char **missing_charset_list; 7443 int missing_charset_count; 7444 char *def_string; 7445 XVaNestedList p_list; 7446 XPoint spot = 7447 {0, 0}; 7448 XFontStruct **fonts; 7449 char **font_name_list; 7450 7451 screen->fs = XCreateFontSet(XtDisplay(xw), 7452 xw->misc.f_x, 7453 &missing_charset_list, 7454 &missing_charset_count, 7455 &def_string); 7456 if (screen->fs == NULL) { 7457 fprintf(stderr, "Preparation of font set " 7458 "\"%s\" for XIM failed.\n", xw->misc.f_x); 7459 screen->fs = XCreateFontSet(XtDisplay(xw), 7460 DEFXIMFONT, 7461 &missing_charset_list, 7462 &missing_charset_count, 7463 &def_string); 7464 } 7465 if (screen->fs == NULL) { 7466 fprintf(stderr, "Preparation of default font set " 7467 "\"%s\" for XIM failed.\n", DEFXIMFONT); 7468 cleanupInputMethod(screen); 7469 xw->misc.cannot_im = True; 7470 return; 7471 } 7472 (void) XExtentsOfFontSet(screen->fs); 7473 j = (unsigned) XFontsOfFontSet(screen->fs, &fonts, &font_name_list); 7474 for (i = 0, screen->fs_ascent = 0; i < j; i++) { 7475 if (screen->fs_ascent < (*fonts)->ascent) 7476 screen->fs_ascent = (*fonts)->ascent; 7477 } 7478 p_list = XVaCreateNestedList(0, 7479 XNSpotLocation, &spot, 7480 XNFontSet, screen->fs, 7481 NULL); 7482 screen->xic = XCreateIC(screen->xim, 7483 XNInputStyle, input_style, 7484 XNClientWindow, XtWindow(xw), 7485 XNFocusWindow, XtWindow(xw), 7486 XNPreeditAttributes, p_list, 7487 NULL); 7488 } else { 7489 screen->xic = XCreateIC(screen->xim, XNInputStyle, input_style, 7490 XNClientWindow, XtWindow(xw), 7491 XNFocusWindow, XtWindow(xw), 7492 NULL); 7493 } 7494 7495 if (!screen->xic) { 7496 fprintf(stderr, "Failed to create input context\n"); 7497 cleanupInputMethod(screen); 7498 } 7499#if defined(USE_XIM_INSTANTIATE_CB) 7500 else { 7501 XIMCallback destroy_cb; 7502 7503 destroy_cb.callback = xim_destroy_cb; 7504 destroy_cb.client_data = NULL; 7505 if (XSetIMValues(screen->xim, XNDestroyCallback, &destroy_cb, NULL)) 7506 fprintf(stderr, "Could not set destroy callback to IM\n"); 7507 } 7508#endif 7509 7510 return; 7511} 7512 7513static void 7514VTInitI18N(XtermWidget xw) 7515{ 7516 if (xw->misc.open_im) { 7517 xim_real_init(xw); 7518 7519#if defined(USE_XIM_INSTANTIATE_CB) 7520 if (TScreenOf(xw)->xic == NULL 7521 && !xw->misc.cannot_im 7522 && xw->misc.retry_im-- > 0) { 7523 sleep(3); 7524 XRegisterIMInstantiateCallback(XtDisplay(xw), NULL, NULL, NULL, 7525 xim_instantiate_cb, NULL); 7526 } 7527#endif 7528 } 7529} 7530#endif /* OPT_I18N_SUPPORT && OPT_INPUT_METHOD */ 7531 7532static void 7533set_cursor_outline_gc(XtermWidget xw, 7534 Bool filled, 7535 Pixel fg, 7536 Pixel bg, 7537 Pixel cc) 7538{ 7539 TScreen *screen = TScreenOf(xw); 7540 VTwin *win = WhichVWin(screen); 7541 CgsEnum cgsId = gcVTcursOutline; 7542 7543 if (cc == bg) 7544 cc = fg; 7545 7546 if (filled) { 7547 setCgsFore(xw, win, cgsId, bg); 7548 setCgsBack(xw, win, cgsId, cc); 7549 } else { 7550 setCgsFore(xw, win, cgsId, cc); 7551 setCgsBack(xw, win, cgsId, bg); 7552 } 7553} 7554 7555static Boolean 7556VTSetValues(Widget cur, 7557 Widget request GCC_UNUSED, 7558 Widget wnew, 7559 ArgList args GCC_UNUSED, 7560 Cardinal *num_args GCC_UNUSED) 7561{ 7562 XtermWidget curvt = (XtermWidget) cur; 7563 XtermWidget newvt = (XtermWidget) wnew; 7564 Boolean refresh_needed = False; 7565 Boolean fonts_redone = False; 7566 7567 if ((T_COLOR(TScreenOf(curvt), TEXT_BG) != 7568 T_COLOR(TScreenOf(newvt), TEXT_BG)) || 7569 (T_COLOR(TScreenOf(curvt), TEXT_FG) != 7570 T_COLOR(TScreenOf(newvt), TEXT_FG)) || 7571 (TScreenOf(curvt)->MenuFontName(TScreenOf(curvt)->menu_font_number) != 7572 TScreenOf(newvt)->MenuFontName(TScreenOf(newvt)->menu_font_number)) || 7573 (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n)) { 7574 if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n) 7575 TScreenOf(newvt)->MenuFontName(fontMenu_default) = newvt->misc.default_font.f_n; 7576 if (xtermLoadFont(newvt, 7577 xtermFontName(TScreenOf(newvt)->MenuFontName(TScreenOf(curvt)->menu_font_number)), 7578 True, TScreenOf(newvt)->menu_font_number)) { 7579 /* resizing does the redisplay, so don't ask for it here */ 7580 refresh_needed = True; 7581 fonts_redone = True; 7582 } else if (curvt->misc.default_font.f_n != newvt->misc.default_font.f_n) 7583 TScreenOf(newvt)->MenuFontName(fontMenu_default) = curvt->misc.default_font.f_n; 7584 } 7585 if (!fonts_redone 7586 && (T_COLOR(TScreenOf(curvt), TEXT_CURSOR) != 7587 T_COLOR(TScreenOf(newvt), TEXT_CURSOR))) { 7588 if (set_cursor_gcs(newvt)) 7589 refresh_needed = True; 7590 } 7591 if (curvt->misc.re_verse != newvt->misc.re_verse) { 7592 newvt->flags ^= REVERSE_VIDEO; 7593 ReverseVideo(newvt); 7594 /* ReverseVideo toggles */ 7595 newvt->misc.re_verse = (Boolean) (!newvt->misc.re_verse); 7596 refresh_needed = True; 7597 } 7598 if ((T_COLOR(TScreenOf(curvt), MOUSE_FG) != 7599 T_COLOR(TScreenOf(newvt), MOUSE_FG)) || 7600 (T_COLOR(TScreenOf(curvt), MOUSE_BG) != 7601 T_COLOR(TScreenOf(newvt), MOUSE_BG))) { 7602 recolor_cursor(TScreenOf(newvt), 7603 TScreenOf(newvt)->pointer_cursor, 7604 T_COLOR(TScreenOf(newvt), MOUSE_FG), 7605 T_COLOR(TScreenOf(newvt), MOUSE_BG)); 7606 refresh_needed = True; 7607 } 7608 if (curvt->misc.scrollbar != newvt->misc.scrollbar) { 7609 ToggleScrollBar(newvt); 7610 } 7611 7612 return refresh_needed; 7613} 7614 7615#define setGC(code) set_at = __LINE__, currentCgs = code 7616 7617#define OutsideSelection(screen,srow,scol) \ 7618 ((srow) > (screen)->endH.row || \ 7619 ((srow) == (screen)->endH.row && \ 7620 (scol) >= (screen)->endH.col) || \ 7621 (srow) < (screen)->startH.row || \ 7622 ((srow) == (screen)->startH.row && \ 7623 (scol) < (screen)->startH.col)) 7624 7625/* 7626 * Shows cursor at new cursor position in screen. 7627 */ 7628void 7629ShowCursor(void) 7630{ 7631 XtermWidget xw = term; 7632 TScreen *screen = TScreenOf(xw); 7633 int x, y; 7634 IChar base; 7635 unsigned flags; 7636 CellColor fg_bg = 0; 7637 GC currentGC; 7638 GC outlineGC; 7639 CgsEnum currentCgs = gcMAX; 7640 VTwin *currentWin = WhichVWin(screen); 7641 int set_at; 7642 Bool in_selection; 7643 Bool reversed; 7644 Bool filled; 7645 Pixel fg_pix; 7646 Pixel bg_pix; 7647 Pixel tmp; 7648#if OPT_HIGHLIGHT_COLOR 7649 Pixel selbg_pix = T_COLOR(screen, HIGHLIGHT_BG); 7650 Pixel selfg_pix = T_COLOR(screen, HIGHLIGHT_FG); 7651 Boolean use_selbg; 7652 Boolean use_selfg; 7653#endif 7654#if OPT_WIDE_CHARS 7655 size_t off; 7656 int my_col = 0; 7657#endif 7658 int cursor_col; 7659 LineData *ld = 0; 7660 7661 if (screen->cursor_state == BLINKED_OFF) 7662 return; 7663 7664 if (screen->eventMode != NORMAL) 7665 return; 7666 7667 if (INX2ROW(screen, screen->cur_row) > screen->max_row) 7668 return; 7669 7670 screen->cursorp.row = screen->cur_row; 7671 cursor_col = screen->cursorp.col = screen->cur_col; 7672 screen->cursor_moved = False; 7673 7674#ifndef NO_ACTIVE_ICON 7675 if (IsIcon(screen)) { 7676 screen->cursor_state = ON; 7677 return; 7678 } 7679#endif /* NO_ACTIVE_ICON */ 7680 7681 ld = getLineData(screen, screen->cur_row); 7682 7683 base = ld->charData[cursor_col]; 7684 flags = ld->attribs[cursor_col]; 7685 7686 if_OPT_WIDE_CHARS(screen, { 7687 if (base == HIDDEN_CHAR && cursor_col > 0) { 7688 /* if cursor points to non-initial part of wide character, 7689 * back it up 7690 */ 7691 --cursor_col; 7692 base = ld->charData[cursor_col]; 7693 } 7694 my_col = cursor_col; 7695 if (base == 0) 7696 base = ' '; 7697 if (isWide((int) base)) 7698 my_col += 1; 7699 }); 7700 7701 if (base == 0) { 7702 base = ' '; 7703 } 7704#if OPT_ISO_COLORS 7705#ifdef EXP_BOGUS_FG 7706 /* 7707 * If the cursor happens to be on blanks, and we have not set both 7708 * foreground and background color, do not treat it as a colored cell. 7709 */ 7710 if (base == ' ') { 7711 if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) { 7712 TRACE(("ShowCursor - do not treat as a colored cell\n")); 7713 flags &= ~(FG_COLOR | BG_COLOR); 7714 } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) { 7715 TRACE(("ShowCursor - should we treat as a colored cell?\n")); 7716 if (!(xw->flags & FG_COLOR)) 7717 if (CheckBogusForeground(screen, "ShowCursor")) 7718 flags &= ~(FG_COLOR | BG_COLOR); 7719 } 7720 } 7721#else /* !EXP_BOGUS_FG */ 7722 /* 7723 * If the cursor happens to be on blanks, and the foreground color is set 7724 * but not the background, do not treat it as a colored cell. 7725 */ 7726 if ((flags & TERM_COLOR_FLAGS(xw)) == BG_COLOR 7727 && base == ' ') { 7728 flags &= ~TERM_COLOR_FLAGS(xw); 7729 } 7730#endif 7731#endif 7732 7733 /* 7734 * Compare the current cell to the last set of colors used for the 7735 * cursor and update the GC's if needed. 7736 */ 7737 if_OPT_ISO_COLORS(screen, { 7738 fg_bg = ld->color[cursor_col]; 7739 }); 7740 7741 fg_pix = getXtermForeground(xw, flags, extract_fg(xw, fg_bg, flags)); 7742 bg_pix = getXtermBackground(xw, flags, extract_bg(xw, fg_bg, flags)); 7743 7744 if (OutsideSelection(screen, screen->cur_row, screen->cur_col)) 7745 in_selection = False; 7746 else 7747 in_selection = True; 7748 7749 reversed = ReverseOrHilite(screen, flags, in_selection); 7750 7751 /* This is like updatedXtermGC(), except that we have to worry about 7752 * whether the window has focus, since in that case we want just an 7753 * outline for the cursor. 7754 */ 7755 filled = (screen->select || screen->always_highlight) && !screen->cursor_underline; 7756#if OPT_HIGHLIGHT_COLOR 7757 use_selbg = isNotForeground(xw, fg_pix, bg_pix, selbg_pix); 7758 use_selfg = isNotBackground(xw, fg_pix, bg_pix, selfg_pix); 7759#endif 7760 if (filled) { 7761 if (reversed) { /* text is reverse video */ 7762 if (getCgsGC(xw, currentWin, gcVTcursNormal)) { 7763 setGC(gcVTcursNormal); 7764 } else { 7765 if (flags & BOLDATTR(screen)) { 7766 setGC(gcBold); 7767 } else { 7768 setGC(gcNorm); 7769 } 7770 } 7771 EXCHANGE(fg_pix, bg_pix, tmp); 7772#if OPT_HIGHLIGHT_COLOR 7773 if (screen->hilite_reverse) { 7774 if (use_selbg && !use_selfg) 7775 fg_pix = bg_pix; 7776 if (use_selfg && !use_selbg) 7777 bg_pix = fg_pix; 7778 if (use_selbg) 7779 bg_pix = selbg_pix; 7780 if (use_selfg) 7781 fg_pix = selfg_pix; 7782 } 7783#endif 7784 } else { /* normal video */ 7785 if (getCgsGC(xw, currentWin, gcVTcursReverse)) { 7786 setGC(gcVTcursReverse); 7787 } else { 7788 if (flags & BOLDATTR(screen)) { 7789 setGC(gcBoldReverse); 7790 } else { 7791 setGC(gcNormReverse); 7792 } 7793 } 7794 } 7795 if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) { 7796 setCgsBack(xw, currentWin, currentCgs, fg_pix); 7797 } 7798 setCgsFore(xw, currentWin, currentCgs, bg_pix); 7799 } else { /* not selected */ 7800 if (reversed) { /* text is reverse video */ 7801 EXCHANGE(fg_pix, bg_pix, tmp); 7802 setGC(gcNormReverse); 7803 } else { /* normal video */ 7804 setGC(gcNorm); 7805 } 7806#if OPT_HIGHLIGHT_COLOR 7807 if (screen->hilite_reverse) { 7808 if (in_selection && !reversed) { 7809 /* EMPTY */ 7810 /* really INVERSE ... */ 7811 ; 7812 } else if (in_selection || reversed) { 7813 if (use_selbg) { 7814 if (use_selfg) { 7815 bg_pix = fg_pix; 7816 } else { 7817 fg_pix = bg_pix; 7818 } 7819 } 7820 if (use_selbg) { 7821 bg_pix = selbg_pix; 7822 } 7823 if (use_selfg) { 7824 fg_pix = selfg_pix; 7825 } 7826 } 7827 } else { 7828 if (in_selection) { 7829 if (use_selbg) { 7830 bg_pix = selbg_pix; 7831 } 7832 if (use_selfg) { 7833 fg_pix = selfg_pix; 7834 } 7835 } 7836 } 7837#endif 7838 setCgsFore(xw, currentWin, currentCgs, fg_pix); 7839 setCgsBack(xw, currentWin, currentCgs, bg_pix); 7840 } 7841 7842 if (screen->cursor_busy == 0 7843 && (screen->cursor_state != ON || screen->cursor_GC != set_at)) { 7844 7845 screen->cursor_GC = set_at; 7846 TRACE(("ShowCursor calling drawXtermText cur(%d,%d) %s-%s, set_at %d\n", 7847 screen->cur_row, screen->cur_col, 7848 (filled ? "filled" : "outline"), 7849 (screen->cursor_underline ? "underline" : "box"), 7850 set_at)); 7851 7852 currentGC = getCgsGC(xw, currentWin, currentCgs); 7853 x = LineCursorX(screen, ld, cursor_col); 7854 y = CursorY(screen, screen->cur_row); 7855 7856 if (screen->cursor_underline) { 7857 /* 7858 * Overriding the combination of filled, reversed, in_selection is 7859 * too complicated since the underline and the text-cell use 7860 * different rules. Just redraw the text-cell, and draw the 7861 * underline on top of it. 7862 */ 7863 HideCursor(); 7864 7865 /* 7866 * Our current-GC is likely to have been modified in HideCursor(). 7867 * Set up a new request. 7868 */ 7869 if (filled) { 7870 if (T_COLOR(screen, TEXT_CURSOR) == xw->dft_foreground) { 7871 setCgsBack(xw, currentWin, currentCgs, fg_pix); 7872 } 7873 setCgsFore(xw, currentWin, currentCgs, bg_pix); 7874 } else { 7875 setCgsFore(xw, currentWin, currentCgs, fg_pix); 7876 setCgsBack(xw, currentWin, currentCgs, bg_pix); 7877 } 7878 } 7879 7880 /* 7881 * Update the outline-gc, to keep the cursor color distinct from the 7882 * background color. 7883 */ 7884 set_cursor_outline_gc(xw, 7885 filled, 7886 fg_pix, 7887 bg_pix, 7888 T_COLOR(screen, TEXT_CURSOR)); 7889 7890 outlineGC = getCgsGC(xw, currentWin, gcVTcursOutline); 7891 if (outlineGC == 0) 7892 outlineGC = currentGC; 7893 7894 if (screen->cursor_underline) { 7895 7896 /* 7897 * Finally, draw the underline. 7898 */ 7899 screen->box->x = (short) x; 7900 screen->box->y = (short) (y + FontHeight(screen) - 2); 7901 XDrawLines(screen->display, VWindow(screen), outlineGC, 7902 screen->box, NBOX, CoordModePrevious); 7903 } else { 7904 7905 drawXtermText(xw, flags & DRAWX_MASK, 7906 currentGC, x, y, 7907 LineCharSet(screen, ld), 7908 &base, 1, 0); 7909 7910#if OPT_WIDE_CHARS 7911 if_OPT_WIDE_CHARS(screen, { 7912 for_each_combData(off, ld) { 7913 if (!(ld->combData[off][my_col])) 7914 break; 7915 drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND, 7916 currentGC, x, y, 7917 LineCharSet(screen, ld), 7918 ld->combData[off] + my_col, 7919 1, isWide((int) base)); 7920 } 7921 }); 7922#endif 7923 7924 if (!filled) { 7925 screen->box->x = (short) x; 7926 screen->box->y = (short) y; 7927 XDrawLines(screen->display, VWindow(screen), outlineGC, 7928 screen->box, NBOX, CoordModePrevious); 7929 } 7930 } 7931 } 7932 screen->cursor_state = ON; 7933 7934 return; 7935} 7936 7937/* 7938 * hide cursor at previous cursor position in screen. 7939 */ 7940void 7941HideCursor(void) 7942{ 7943 XtermWidget xw = term; 7944 TScreen *screen = TScreenOf(xw); 7945 GC currentGC; 7946 int x, y; 7947 IChar base; 7948 unsigned flags; 7949 CellColor fg_bg = 0; 7950 Bool in_selection; 7951#if OPT_WIDE_CHARS 7952 size_t off; 7953 int my_col = 0; 7954#endif 7955 int cursor_col; 7956 LineData *ld = 0; 7957 7958 if (screen->cursor_state == OFF) 7959 return; 7960 if (INX2ROW(screen, screen->cursorp.row) > screen->max_row) 7961 return; 7962 7963 cursor_col = screen->cursorp.col; 7964 7965#ifndef NO_ACTIVE_ICON 7966 if (IsIcon(screen)) { 7967 screen->cursor_state = OFF; 7968 return; 7969 } 7970#endif /* NO_ACTIVE_ICON */ 7971 7972 ld = getLineData(screen, screen->cursorp.row); 7973 7974 base = ld->charData[cursor_col]; 7975 flags = ld->attribs[cursor_col]; 7976 7977 if_OPT_WIDE_CHARS(screen, { 7978 if (base == HIDDEN_CHAR && cursor_col > 0) { 7979 /* if cursor points to non-initial part of wide character, 7980 * back it up 7981 */ 7982 --cursor_col; 7983 base = ld->charData[cursor_col]; 7984 } 7985 my_col = cursor_col; 7986 if (base == 0) 7987 base = ' '; 7988 if (isWide((int) base)) 7989 my_col += 1; 7990 }); 7991 7992 if (base == 0) { 7993 base = ' '; 7994 } 7995#ifdef EXP_BOGUS_FG 7996 /* 7997 * If the cursor happens to be on blanks, and we have not set both 7998 * foreground and background color, do not treat it as a colored cell. 7999 */ 8000#if OPT_ISO_COLORS 8001 if (base == ' ') { 8002 if ((flags & (FG_COLOR | BG_COLOR)) == BG_COLOR) { 8003 TRACE(("HideCursor - do not treat as a colored cell\n")); 8004 flags &= ~(FG_COLOR | BG_COLOR); 8005 } else if ((flags & (FG_COLOR | BG_COLOR)) == FG_COLOR) { 8006 TRACE(("HideCursor - should we treat as a colored cell?\n")); 8007 if (!(xw->flags & FG_COLOR)) 8008 if (CheckBogusForeground(screen, "HideCursor")) 8009 flags &= ~(FG_COLOR | BG_COLOR); 8010 } 8011 } 8012#endif 8013#endif 8014#if OPT_ISO_COLORS 8015 fg_bg = 0; 8016#endif 8017 8018 /* 8019 * Compare the current cell to the last set of colors used for the 8020 * cursor and update the GC's if needed. 8021 */ 8022 if_OPT_ISO_COLORS(screen, { 8023 fg_bg = ld->color[cursor_col]; 8024 }); 8025 8026 if (OutsideSelection(screen, screen->cursorp.row, screen->cursorp.col)) 8027 in_selection = False; 8028 else 8029 in_selection = True; 8030 8031 currentGC = updatedXtermGC(xw, flags, fg_bg, in_selection); 8032 8033 TRACE(("HideCursor calling drawXtermText cur(%d,%d)\n", 8034 screen->cursorp.row, screen->cursorp.col)); 8035 8036 x = LineCursorX(screen, ld, cursor_col); 8037 y = CursorY(screen, screen->cursorp.row); 8038 8039 drawXtermText(xw, flags & DRAWX_MASK, 8040 currentGC, x, y, 8041 LineCharSet(screen, ld), 8042 &base, 1, 0); 8043 8044#if OPT_WIDE_CHARS 8045 if_OPT_WIDE_CHARS(screen, { 8046 for_each_combData(off, ld) { 8047 if (!(ld->combData[off][my_col])) 8048 break; 8049 drawXtermText(xw, (flags & DRAWX_MASK) | NOBACKGROUND, 8050 currentGC, x, y, 8051 LineCharSet(screen, ld), 8052 ld->combData[off] + my_col, 8053 1, isWide((int) base)); 8054 } 8055 }); 8056#endif 8057 screen->cursor_state = OFF; 8058 resetXtermGC(xw, flags, in_selection); 8059 8060 return; 8061} 8062 8063#if OPT_BLINK_CURS || OPT_BLINK_TEXT 8064static void 8065StartBlinking(TScreen * screen) 8066{ 8067 if (screen->blink_timer == 0) { 8068 unsigned long interval = (unsigned long) ((screen->cursor_state == ON) 8069 ? screen->blink_on 8070 : screen->blink_off); 8071 if (interval == 0) /* wow! */ 8072 interval = 1; /* let's humor him anyway */ 8073 screen->blink_timer = XtAppAddTimeOut(app_con, 8074 interval, 8075 HandleBlinking, 8076 screen); 8077 } 8078} 8079 8080static void 8081StopBlinking(TScreen * screen) 8082{ 8083 if (screen->blink_timer) 8084 XtRemoveTimeOut(screen->blink_timer); 8085 screen->blink_timer = 0; 8086} 8087 8088#if OPT_BLINK_TEXT 8089static Bool 8090LineHasBlinking(TScreen * screen, LineData * ld) 8091{ 8092 int col; 8093 Bool result = False; 8094 8095 for (col = 0; col < MaxCols(screen); ++col) { 8096 if (ld->attribs[col] & BLINK) { 8097 result = True; 8098 break; 8099 } 8100 } 8101 return result; 8102} 8103#endif 8104 8105/* 8106 * Blink the cursor by alternately showing/hiding cursor. We leave the timer 8107 * running all the time (even though that's a little inefficient) to make the 8108 * logic simple. 8109 */ 8110static void 8111HandleBlinking(XtPointer closure, XtIntervalId * id GCC_UNUSED) 8112{ 8113 TScreen *screen = (TScreen *) closure; 8114 Bool resume = False; 8115 8116 screen->blink_timer = 0; 8117 screen->blink_state = !screen->blink_state; 8118 8119#if OPT_BLINK_CURS 8120 if (DoStartBlinking(screen)) { 8121 if (screen->cursor_state == ON) { 8122 if (screen->select || screen->always_highlight) { 8123 HideCursor(); 8124 if (screen->cursor_state == OFF) 8125 screen->cursor_state = BLINKED_OFF; 8126 } 8127 } else if (screen->cursor_state == BLINKED_OFF) { 8128 screen->cursor_state = OFF; 8129 ShowCursor(); 8130 if (screen->cursor_state == OFF) 8131 screen->cursor_state = BLINKED_OFF; 8132 } 8133 resume = True; 8134 } 8135#endif 8136 8137#if OPT_BLINK_TEXT 8138 /* 8139 * Inspect the lines on the current screen to see if any have the BLINK flag 8140 * associated with them. Prune off any that have had the corresponding 8141 * cells reset. If any are left, repaint those lines with ScrnRefresh(). 8142 */ 8143 if (!(screen->blink_as_bold)) { 8144 int row; 8145 int first_row = screen->max_row; 8146 int last_row = -1; 8147 8148 for (row = screen->max_row; row >= 0; row--) { 8149 LineData *ld = getLineData(screen, ROW2INX(screen, row)); 8150 8151 if (ld != 0 && LineTstBlinked(ld)) { 8152 if (LineHasBlinking(screen, ld)) { 8153 resume = True; 8154 if (row > last_row) 8155 last_row = row; 8156 if (row < first_row) 8157 first_row = row; 8158 } else { 8159 LineClrBlinked(ld); 8160 } 8161 } 8162 } 8163 /* 8164 * FIXME: this could be a little more efficient, e.g,. by limiting the 8165 * columns which are updated. 8166 */ 8167 if (first_row <= last_row) { 8168 ScrnRefresh(term, 8169 first_row, 8170 0, 8171 last_row + 1 - first_row, 8172 MaxCols(screen), 8173 True); 8174 } 8175 } 8176#endif 8177 8178 /* 8179 * If either the cursor or text is blinking, restart the timer. 8180 */ 8181 if (resume) 8182 StartBlinking(screen); 8183} 8184#endif /* OPT_BLINK_CURS || OPT_BLINK_TEXT */ 8185 8186void 8187RestartBlinking(TScreen * screen GCC_UNUSED) 8188{ 8189#if OPT_BLINK_CURS || OPT_BLINK_TEXT 8190 if (screen->blink_timer == 0) { 8191 Bool resume = False; 8192 8193#if OPT_BLINK_CURS 8194 if (DoStartBlinking(screen)) { 8195 resume = True; 8196 } 8197#endif 8198#if OPT_BLINK_TEXT 8199 if (!resume) { 8200 int row; 8201 8202 for (row = screen->max_row; row >= 0; row--) { 8203 LineData *ld = getLineData(screen, ROW2INX(screen, row)); 8204 8205 if (ld != 0 && LineTstBlinked(ld)) { 8206 if (LineHasBlinking(screen, ld)) { 8207 resume = True; 8208 break; 8209 } 8210 } 8211 } 8212 } 8213#endif 8214 if (resume) 8215 StartBlinking(screen); 8216 } 8217#endif 8218} 8219 8220/* 8221 * Implement soft or hard (full) reset of the VTxxx emulation. There are a 8222 * couple of differences from real DEC VTxxx terminals (to avoid breaking 8223 * applications which have come to rely on xterm doing this): 8224 * 8225 * + autowrap mode should be reset (instead it's reset to the resource 8226 * default). 8227 * + the popup menu offers a choice of resetting the savedLines, or not. 8228 * (but the control sequence does this anyway). 8229 */ 8230void 8231VTReset(XtermWidget xw, Bool full, Bool saved) 8232{ 8233 static char empty[1]; 8234 8235 TScreen *screen = TScreenOf(xw); 8236 8237 if (!XtIsRealized((Widget) xw) || (CURRENT_EMU() != (Widget) xw)) { 8238 Bell(xw, XkbBI_MinorError, 0); 8239 return; 8240 } 8241 8242 if (saved) { 8243 screen->savedlines = 0; 8244 ScrollBarDrawThumb(screen->scrollWidget); 8245 } 8246 8247 /* make cursor visible */ 8248 screen->cursor_set = ON; 8249 8250 /* reset scrolling region */ 8251 set_tb_margins(screen, 0, screen->max_row); 8252 8253 bitclr(&xw->flags, ORIGIN); 8254 8255 if_OPT_ISO_COLORS(screen, { 8256 reset_SGR_Colors(xw); 8257 if (ResetAnsiColorRequest(xw, empty, 0)) 8258 xtermRepaint(xw); 8259 }); 8260 8261 /* Reset character-sets to initial state */ 8262 resetCharsets(screen); 8263 8264#if OPT_MOD_FKEYS 8265 /* Reset modifier-resources to initial state */ 8266 xw->keyboard.modify_now = xw->keyboard.modify_1st; 8267#endif 8268 8269 /* Reset DECSCA */ 8270 bitclr(&xw->flags, PROTECTED); 8271 screen->protected_mode = OFF_PROTECT; 8272 8273 if (full) { /* RIS */ 8274 if (screen->bellOnReset) 8275 Bell(xw, XkbBI_TerminalBell, 0); 8276 8277 /* reset the mouse mode */ 8278 screen->send_mouse_pos = MOUSE_OFF; 8279 screen->send_focus_pos = OFF; 8280 screen->ext_mode_mouse = OFF; 8281 screen->waitingForTrackInfo = False; 8282 screen->eventMode = NORMAL; 8283 8284 xtermShowPointer(xw, True); 8285 8286 TabReset(xw->tabs); 8287 xw->keyboard.flags = MODE_SRM; 8288#if OPT_INITIAL_ERASE 8289 if (xw->keyboard.reset_DECBKM == 1) 8290 xw->keyboard.flags |= MODE_DECBKM; 8291 else if (xw->keyboard.reset_DECBKM == 2) 8292#endif 8293 if (TScreenOf(xw)->backarrow_key) 8294 xw->keyboard.flags |= MODE_DECBKM; 8295 TRACE(("full reset DECBKM %s\n", 8296 BtoS(xw->keyboard.flags & MODE_DECBKM))); 8297 update_appcursor(); 8298 update_appkeypad(); 8299 update_decbkm(); 8300 show_8bit_control(False); 8301 reset_decudk(); 8302 8303 FromAlternate(xw); 8304 ClearScreen(xw); 8305 screen->cursor_state = OFF; 8306 if (xw->flags & REVERSE_VIDEO) 8307 ReverseVideo(xw); 8308 8309 xw->flags = xw->initflags; 8310 update_reversevideo(); 8311 update_autowrap(); 8312 update_reversewrap(); 8313 update_autolinefeed(); 8314 8315 screen->jumpscroll = (Boolean) (!(xw->flags & SMOOTHSCROLL)); 8316 update_jumpscroll(); 8317 8318 if (screen->c132 && (xw->flags & IN132COLUMNS)) { 8319 Dimension reqWidth = (Dimension) (80 * FontWidth(screen) 8320 + 2 * screen->border 8321 + ScrollbarWidth(screen)); 8322 Dimension reqHeight = (Dimension) (FontHeight(screen) 8323 * MaxRows(screen) 8324 + 2 * screen->border); 8325 Dimension replyWidth; 8326 Dimension replyHeight; 8327 8328 TRACE(("Making resize-request to restore 80-columns %dx%d\n", 8329 reqHeight, reqWidth)); 8330 REQ_RESIZE((Widget) xw, 8331 reqWidth, 8332 reqHeight, 8333 &replyWidth, &replyHeight); 8334 repairSizeHints(); 8335 XSync(screen->display, False); /* synchronize */ 8336 if (XtAppPending(app_con)) 8337 xevents(); 8338 } 8339 8340 CursorSet(screen, 0, 0, xw->flags); 8341 CursorSave(xw); 8342 } else { /* DECSTR */ 8343 /* 8344 * There's a tiny difference, to accommodate usage of xterm. 8345 * We reset autowrap to the resource values rather than turning 8346 * it off. 8347 */ 8348 UIntClr(xw->keyboard.flags, (MODE_DECCKM | MODE_KAM | MODE_DECKPAM)); 8349 bitcpy(&xw->flags, xw->initflags, WRAPAROUND | REVERSEWRAP); 8350 bitclr(&xw->flags, INSERT | INVERSE | BOLD | BLINK | UNDERLINE | INVISIBLE); 8351 if_OPT_ISO_COLORS(screen, { 8352 reset_SGR_Colors(xw); 8353 }); 8354 update_appcursor(); 8355 update_autowrap(); 8356 update_reversewrap(); 8357 8358 CursorSave(xw); 8359 screen->sc[screen->whichBuf].row = 8360 screen->sc[screen->whichBuf].col = 0; 8361 } 8362 longjmp(vtjmpbuf, 1); /* force ground state in parser */ 8363} 8364 8365/* 8366 * set_character_class - takes a string of the form 8367 * 8368 * low[-high]:val[,low[-high]:val[...]] 8369 * 8370 * and sets the indicated ranges to the indicated values. 8371 */ 8372static int 8373set_character_class(char *s) 8374{ 8375 int i; /* iterator, index into s */ 8376 int len; /* length of s */ 8377 int acc; /* accumulator */ 8378 int low, high; /* bounds of range [0..127] */ 8379 int base; /* 8, 10, 16 (octal, decimal, hex) */ 8380 int numbers; /* count of numbers per range */ 8381 int digits; /* count of digits in a number */ 8382 static const char errfmt[] = "%s: %s in range string \"%s\" (position %d)\n"; 8383 8384 if (!s || !s[0]) 8385 return -1; 8386 8387 base = 10; /* in case we ever add octal, hex */ 8388 low = high = -1; /* out of range */ 8389 8390 for (i = 0, len = (int) strlen(s), acc = 0, numbers = digits = 0; 8391 i < len; i++) { 8392 Char c = CharOf(s[i]); 8393 8394 if (isspace(c)) { 8395 continue; 8396 } else if (isdigit(c)) { 8397 acc = acc * base + (c - '0'); 8398 digits++; 8399 continue; 8400 } else if (c == '-') { 8401 low = acc; 8402 acc = 0; 8403 if (digits == 0) { 8404 fprintf(stderr, errfmt, ProgramName, "missing number", s, i); 8405 return (-1); 8406 } 8407 digits = 0; 8408 numbers++; 8409 continue; 8410 } else if (c == ':') { 8411 if (numbers == 0) 8412 low = acc; 8413 else if (numbers == 1) 8414 high = acc; 8415 else { 8416 fprintf(stderr, errfmt, ProgramName, "too many numbers", 8417 s, i); 8418 return (-1); 8419 } 8420 digits = 0; 8421 numbers++; 8422 acc = 0; 8423 continue; 8424 } else if (c == ',') { 8425 /* 8426 * now, process it 8427 */ 8428 8429 if (high < 0) { 8430 high = low; 8431 numbers++; 8432 } 8433 if (numbers != 2) { 8434 fprintf(stderr, errfmt, ProgramName, "bad value number", 8435 s, i); 8436 } else if (SetCharacterClassRange(low, high, acc) != 0) { 8437 fprintf(stderr, errfmt, ProgramName, "bad range", s, i); 8438 } 8439 8440 low = high = -1; 8441 acc = 0; 8442 digits = 0; 8443 numbers = 0; 8444 continue; 8445 } else { 8446 fprintf(stderr, errfmt, ProgramName, "bad character", s, i); 8447 return (-1); 8448 } /* end if else if ... else */ 8449 8450 } 8451 8452 if (low < 0 && high < 0) 8453 return (0); 8454 8455 /* 8456 * now, process it 8457 */ 8458 8459 if (high < 0) 8460 high = low; 8461 if (numbers < 1 || numbers > 2) { 8462 fprintf(stderr, errfmt, ProgramName, "bad value number", s, i); 8463 } else if (SetCharacterClassRange(low, high, acc) != 0) { 8464 fprintf(stderr, errfmt, ProgramName, "bad range", s, i); 8465 } 8466 8467 return (0); 8468} 8469 8470/* ARGSUSED */ 8471static void 8472HandleKeymapChange(Widget w, 8473 XEvent * event GCC_UNUSED, 8474 String * params, 8475 Cardinal *param_count) 8476{ 8477 static XtTranslations keymap, original; 8478 static XtResource key_resources[] = 8479 { 8480 {XtNtranslations, XtCTranslations, XtRTranslationTable, 8481 sizeof(XtTranslations), 0, XtRTranslationTable, (XtPointer) NULL} 8482 }; 8483 char mapName[1000]; 8484 char mapClass[1000]; 8485 char *pmapName; 8486 char *pmapClass; 8487 size_t len; 8488 8489 if (*param_count != 1) 8490 return; 8491 8492 if (original == NULL) 8493 original = w->core.tm.translations; 8494 8495 if (strcmp(params[0], "None") == 0) { 8496 XtOverrideTranslations(w, original); 8497 return; 8498 } 8499 8500 len = strlen(params[0]) + 7; 8501 8502 pmapName = (char *) MyStackAlloc(len, mapName); 8503 pmapClass = (char *) MyStackAlloc(len, mapClass); 8504 if (pmapName == NULL 8505 || pmapClass == NULL) { 8506 SysError(ERROR_KMMALLOC1); 8507 } else { 8508 8509 (void) sprintf(pmapName, "%sKeymap", params[0]); 8510 (void) strcpy(pmapClass, pmapName); 8511 if (islower(CharOf(pmapClass[0]))) 8512 pmapClass[0] = x_toupper(pmapClass[0]); 8513 XtGetSubresources(w, (XtPointer) &keymap, pmapName, pmapClass, 8514 key_resources, (Cardinal) 1, NULL, (Cardinal) 0); 8515 if (keymap != NULL) 8516 XtOverrideTranslations(w, keymap); 8517 8518 MyStackFree(pmapName, mapName); 8519 MyStackFree(pmapClass, mapClass); 8520 } 8521} 8522 8523/* ARGSUSED */ 8524static void 8525HandleBell(Widget w GCC_UNUSED, 8526 XEvent * event GCC_UNUSED, 8527 String * params, /* [0] = volume */ 8528 Cardinal *param_count) /* 0 or 1 */ 8529{ 8530 int percent = (*param_count) ? atoi(params[0]) : 0; 8531 8532 Bell(term, XkbBI_TerminalBell, percent); 8533} 8534 8535/* ARGSUSED */ 8536static void 8537HandleVisualBell(Widget w GCC_UNUSED, 8538 XEvent * event GCC_UNUSED, 8539 String * params GCC_UNUSED, 8540 Cardinal *param_count GCC_UNUSED) 8541{ 8542 VisualBell(); 8543} 8544 8545/* ARGSUSED */ 8546static void 8547HandleIgnore(Widget w, 8548 XEvent * event, 8549 String * params GCC_UNUSED, 8550 Cardinal *param_count GCC_UNUSED) 8551{ 8552 XtermWidget xw; 8553 8554 TRACE(("Handle ignore for %p\n", (void *) w)); 8555 if ((xw = getXtermWidget(w)) != 0) { 8556 /* do nothing, but check for funny escape sequences */ 8557 (void) SendMousePosition(xw, event); 8558 } 8559} 8560 8561/* ARGSUSED */ 8562static void 8563DoSetSelectedFont(Widget w, 8564 XtPointer client_data GCC_UNUSED, 8565 Atom * selection GCC_UNUSED, 8566 Atom * type, 8567 XtPointer value, 8568 unsigned long *length, 8569 int *format) 8570{ 8571 XtermWidget xw = getXtermWidget(w); 8572 8573 if ((xw == 0) || *type != XA_STRING || *format != 8) { 8574 Bell(xw, XkbBI_MinorError, 0); 8575 } else { 8576 Boolean failed = False; 8577 int oldFont = TScreenOf(xw)->menu_font_number; 8578 String save = TScreenOf(xw)->MenuFontName(fontMenu_fontsel); 8579 char *val; 8580 char *test = 0; 8581 char *used = 0; 8582 unsigned len = (unsigned) *length; 8583 unsigned tst; 8584 8585 /* 8586 * Some versions of X deliver null-terminated selections, some do not. 8587 */ 8588 for (tst = 0; tst < len; ++tst) { 8589 if (((char *) value)[tst] == '\0') { 8590 len = tst; 8591 break; 8592 } 8593 } 8594 8595 if (len > 0 && (val = TypeMallocN(char, len + 1)) != 0) { 8596 memcpy(val, value, (size_t) len); 8597 val[len] = '\0'; 8598 used = x_strtrim(val); 8599 TRACE(("DoSetSelectedFont(%s)\n", used)); 8600 /* Do some sanity checking to avoid sending a long selection 8601 back to the server in an OpenFont that is unlikely to succeed. 8602 XLFD allows up to 255 characters and no control characters; 8603 we are a little more liberal here. */ 8604 if (len < 1000 8605 && !strchr(used, '\n') 8606 && (test = x_strdup(used)) != 0) { 8607 TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = test; 8608 if (!xtermLoadFont(term, 8609 xtermFontName(used), 8610 True, 8611 fontMenu_fontsel)) { 8612 failed = True; 8613 free(test); 8614 TScreenOf(xw)->MenuFontName(fontMenu_fontsel) = save; 8615 } 8616 } else { 8617 failed = True; 8618 } 8619 if (failed) { 8620 (void) xtermLoadFont(term, 8621 xtermFontName(TScreenOf(xw)->MenuFontName(oldFont)), 8622 True, 8623 oldFont); 8624 Bell(xw, XkbBI_MinorError, 0); 8625 } 8626 free(used); 8627 free(val); 8628 } 8629 } 8630} 8631 8632void 8633FindFontSelection(XtermWidget xw, const char *atom_name, Bool justprobe) 8634{ 8635 TScreen *screen = TScreenOf(xw); 8636 static AtomPtr *atoms; 8637 unsigned int atomCount = 0; 8638 AtomPtr *pAtom; 8639 unsigned a; 8640 Atom target; 8641 8642 if (!atom_name) 8643 atom_name = (screen->mappedSelect 8644 ? screen->mappedSelect[0] 8645 : "PRIMARY"); 8646 TRACE(("FindFontSelection(%s)\n", atom_name)); 8647 8648 for (pAtom = atoms, a = atomCount; a; a--, pAtom++) { 8649 if (strcmp(atom_name, XmuNameOfAtom(*pAtom)) == 0) 8650 break; 8651 } 8652 if (!a) { 8653 atoms = TypeXtReallocN(AtomPtr, atoms, atomCount + 1); 8654 *(pAtom = &atoms[atomCount]) = XmuMakeAtom(atom_name); 8655 } 8656 8657 target = XmuInternAtom(XtDisplay(xw), *pAtom); 8658 if (justprobe) { 8659 screen->MenuFontName(fontMenu_fontsel) = 8660 XGetSelectionOwner(XtDisplay(xw), target) ? _Font_Selected_ : 0; 8661 TRACE(("...selected fontname '%s'\n", 8662 NonNull(screen->MenuFontName(fontMenu_fontsel)))); 8663 } else { 8664 XtGetSelectionValue((Widget) xw, target, XA_STRING, 8665 DoSetSelectedFont, NULL, 8666 XtLastTimestampProcessed(XtDisplay(xw))); 8667 } 8668 return; 8669} 8670 8671Bool 8672set_cursor_gcs(XtermWidget xw) 8673{ 8674 TScreen *screen = TScreenOf(xw); 8675 VTwin *win = WhichVWin(screen); 8676 8677 Pixel cc = T_COLOR(screen, TEXT_CURSOR); 8678 Pixel fg = T_COLOR(screen, TEXT_FG); 8679 Pixel bg = T_COLOR(screen, TEXT_BG); 8680 Bool changed = False; 8681 8682 /* 8683 * Let's see, there are three things that have "color": 8684 * 8685 * background 8686 * text 8687 * cursorblock 8688 * 8689 * And, there are four situations when drawing a cursor, if we decide 8690 * that we like have a solid block of cursor color with the letter 8691 * that it is highlighting shown in the background color to make it 8692 * stand out: 8693 * 8694 * selected window, normal video - background on cursor 8695 * selected window, reverse video - foreground on cursor 8696 * unselected window, normal video - foreground on background 8697 * unselected window, reverse video - background on foreground 8698 * 8699 * Since the last two are really just normalGC and reverseGC, we only 8700 * need two new GC's. Under monochrome, we get the same effect as 8701 * above by setting cursor color to foreground. 8702 */ 8703 8704 TRACE(("set_cursor_gcs cc=%#lx, fg=%#lx, bg=%#lx\n", cc, fg, bg)); 8705 if (win != 0 && (cc != bg)) { 8706 /* set the fonts to the current one */ 8707 setCgsFont(xw, win, gcVTcursNormal, 0); 8708 setCgsFont(xw, win, gcVTcursFilled, 0); 8709 setCgsFont(xw, win, gcVTcursReverse, 0); 8710 setCgsFont(xw, win, gcVTcursOutline, 0); 8711 8712 /* we have a colored cursor */ 8713 setCgsFore(xw, win, gcVTcursNormal, fg); 8714 setCgsBack(xw, win, gcVTcursNormal, cc); 8715 8716 setCgsFore(xw, win, gcVTcursFilled, cc); 8717 setCgsBack(xw, win, gcVTcursFilled, fg); 8718 8719 if (screen->always_highlight) { 8720 /* both GC's use the same color */ 8721 setCgsFore(xw, win, gcVTcursReverse, bg); 8722 setCgsBack(xw, win, gcVTcursReverse, cc); 8723 } else { 8724 setCgsFore(xw, win, gcVTcursReverse, bg); 8725 setCgsBack(xw, win, gcVTcursReverse, cc); 8726 } 8727 set_cursor_outline_gc(xw, screen->always_highlight, fg, bg, cc); 8728 changed = True; 8729 } 8730 8731 if (changed) { 8732 TRACE(("...set_cursor_gcs - done\n")); 8733 } 8734 return changed; 8735} 8736 8737/* 8738 * Build up the default translations string, allowing the user to suppress 8739 * some of the features. 8740 */ 8741void 8742VTInitTranslations(void) 8743{ 8744 /* *INDENT-OFF* */ 8745 static struct { 8746 Boolean wanted; 8747 const char *name; 8748 const char *value; 8749 } table[] = { 8750 { 8751 False, 8752 "default", 8753"\ 8754 Shift <KeyPress> Prior:scroll-back(1,halfpage) \n\ 8755 Shift <KeyPress> Next:scroll-forw(1,halfpage) \n\ 8756 Shift <KeyPress> Select:select-cursor-start() select-cursor-end(SELECT, CUT_BUFFER0) \n\ 8757 Shift <KeyPress> Insert:insert-selection(SELECT, CUT_BUFFER0) \n\ 8758" 8759 }, 8760#if OPT_MAXIMIZE 8761 { 8762 False, 8763 "fullscreen", 8764"\ 8765 Alt <Key>Return:fullscreen() \n\ 8766" 8767 }, 8768#endif 8769#if OPT_SCROLL_LOCK 8770 { 8771 False, 8772 "scroll-lock", 8773"\ 8774 <KeyRelease> Scroll_Lock:scroll-lock() \n\ 8775" 8776 }, 8777#endif 8778#if OPT_SHIFT_FONTS 8779 { 8780 False, 8781 "shift-fonts", 8782"\ 8783 Shift~Ctrl <KeyPress> KP_Add:larger-vt-font() \n\ 8784 Shift Ctrl <KeyPress> KP_Add:smaller-vt-font() \n\ 8785 Shift <KeyPress> KP_Subtract:smaller-vt-font() \n\ 8786" 8787 }, 8788#endif 8789 /* PROCURA added "Meta <Btn2Down>:clear-saved-lines()" */ 8790 { 8791 False, 8792 "default", 8793"\ 8794 ~Meta <KeyPress>:insert-seven-bit() \n\ 8795 Meta <KeyPress>:insert-eight-bit() \n\ 8796 !Ctrl <Btn1Down>:popup-menu(mainMenu) \n\ 8797 !Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\ 8798 !Lock Ctrl @Num_Lock <Btn1Down>:popup-menu(mainMenu) \n\ 8799 ! @Num_Lock Ctrl <Btn1Down>:popup-menu(mainMenu) \n\ 8800 ~Meta <Btn1Down>:select-start() \n\ 8801 ~Meta <Btn1Motion>:select-extend() \n\ 8802 !Ctrl <Btn2Down>:popup-menu(vtMenu) \n\ 8803 !Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\ 8804 !Lock Ctrl @Num_Lock <Btn2Down>:popup-menu(vtMenu) \n\ 8805 ! @Num_Lock Ctrl <Btn2Down>:popup-menu(vtMenu) \n\ 8806 ~Ctrl ~Meta <Btn2Down>:ignore() \n\ 8807 Meta <Btn2Down>:clear-saved-lines() \n\ 8808 ~Ctrl ~Meta <Btn2Up>:insert-selection(SELECT, CUT_BUFFER0) \n\ 8809 !Ctrl <Btn3Down>:popup-menu(fontMenu) \n\ 8810 !Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\ 8811 !Lock Ctrl @Num_Lock <Btn3Down>:popup-menu(fontMenu) \n\ 8812 ! @Num_Lock Ctrl <Btn3Down>:popup-menu(fontMenu) \n\ 8813 ~Ctrl ~Meta <Btn3Down>:start-extend() \n\ 8814 ~Meta <Btn3Motion>:select-extend() \n\ 8815" 8816 }, 8817 { 8818 False, 8819 "wheel-mouse", 8820"\ 8821 Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 8822 Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 8823 Lock @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 8824 @Num_Lock Ctrl <Btn4Down>:scroll-back(1,halfpage,m) \n\ 8825 <Btn4Down>:scroll-back(5,line,m) \n\ 8826 Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 8827 Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 8828 Lock @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 8829 @Num_Lock Ctrl <Btn5Down>:scroll-forw(1,halfpage,m) \n\ 8830 <Btn5Down>:scroll-forw(5,line,m) \n\ 8831" 8832 }, 8833 { 8834 False, 8835 "default", 8836"\ 8837 <BtnUp>:select-end(SELECT, CUT_BUFFER0) \n\ 8838 <BtnDown>:ignore() \ 8839" 8840 } 8841 }; 8842 /* *INDENT-ON* */ 8843 8844 size_t needed = 0; 8845 char *result = 0; 8846 8847 int pass; 8848 Cardinal item; 8849 8850 TRACE(("VTInitTranslations\n")); 8851 for (item = 0; item < XtNumber(table); ++item) { 8852 table[item].wanted = True; 8853 } 8854#if OPT_MAXIMIZE 8855 /* 8856 * As a special case, allow for disabling the alt-enter translation if 8857 * the resource settings prevent fullscreen from being used. We would 8858 * do the same for scroll-lock and shift-fonts if they were application 8859 * resources too, rather than in the widget. 8860 */ 8861 if (resource.fullscreen == esNever) { 8862 for (item = 0; item < XtNumber(table); ++item) { 8863 if (!strcmp(table[item].name, "fullscreen")) 8864 table[item].wanted = False; 8865 } 8866 } 8867#endif 8868 if (!IsEmpty(resource.omitTranslation)) { 8869 char *value; 8870 const char *source = resource.omitTranslation; 8871 8872 while (*source != '\0' && (value = ParseList(&source)) != 0) { 8873 size_t len = strlen(value); 8874 8875 TRACE(("parsed:%s\n", value)); 8876 for (item = 0; item < XtNumber(table); ++item) { 8877 if (strlen(table[item].name) >= len 8878 && x_strncasecmp(table[item].name, 8879 value, 8880 (unsigned) len) == 0) { 8881 table[item].wanted = False; 8882 TRACE(("omit(%s):\n%s\n", table[item].name, table[item].value)); 8883 break; 8884 } 8885 } 8886 free(value); 8887 } 8888 } 8889 8890 for (pass = 0; pass < 2; ++pass) { 8891 needed = 0; 8892 for (item = 0; item < XtNumber(table); ++item) { 8893 if (table[item].wanted) { 8894 if (pass) { 8895 strcat(result, table[item].value); 8896 } else { 8897 needed += strlen(table[item].value) + 1; 8898 } 8899 } 8900 } 8901 if (!pass) { 8902 result = XtMalloc((Cardinal) needed); 8903 *result = '\0'; 8904 } 8905 } 8906 8907 TRACE(("result:\n%s\n", result)); 8908 8909 defaultTranslations = result; 8910 xtermClassRec.core_class.tm_table = result; 8911} 8912 8913#ifdef NO_LEAKS 8914void 8915noleaks_charproc(void) 8916{ 8917 if (v_buffer != 0) 8918 free(v_buffer); 8919} 8920#endif 8921