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