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