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